查找本地進程的jmx url的代碼
好久沒寫blog了,先來篇充充數。。
當想用JMX連接本地進程,而這個進程又沒有配置JMX相關的參數,怎樣才能連到這個進程?
下麵的代碼是從ActiveMQ的代碼裏摳出來的,可以得到本地進程的jmx url。
不過當目標進程配置了-Djava.io.tmpdir 參數時,不能正常工作,原因是JDK的bug。
參考:
https://dikar.iteye.com/blog/1415408
https://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6649594
所以ActiveMQ5.8在用命令行時,用 "./activemq-admin list" ,得不出結果,改用"./activemq list "就可以了。
原因是"activemq-admin"這個腳本裏,配置了一個java.io.tmpdir 的參數。
給ActiveMQ提了個issue,不過貌似沒人理。。
https://issues.apache.org/jira/browse/AMQ-4541
import java.io.File; import java.lang.reflect.Method; import java.net.URL; import java.net.URLClassLoader; import java.util.List; import java.util.Properties; public class AbstractJmxCommand { private static final String CONNECTOR_ADDRESS = "com.sun.management.jmxremote.localConnectorAddress"; public static String getJVM() { return System.getProperty("java.vm.specification.vendor"); } public static boolean isSunJVM() { // need to check for Oracle as that is the name for Java7 onwards. return getJVM().equals("Sun Microsystems Inc.") || getJVM().startsWith("Oracle"); } /** * Finds the JMX Url for a VM by its process id * * @param pid * The process id value of the VM to search for. * * @return the JMX Url of the VM with the given pid or null if not found. */ @SuppressWarnings({ "rawtypes", "unchecked" }) protected String findJMXUrlByProcessId(int pid) { if (isSunJVM()) { try { // Classes are all dynamically loaded, since they are specific to Sun VM // if it fails for any reason default jmx url will be used // tools.jar are not always included used by default class loader, so we // will try to use custom loader that will try to load tools.jar String javaHome = System.getProperty("java.home"); String tools = javaHome + File.separator + ".." + File.separator + "lib" + File.separator + "tools.jar"; URLClassLoader loader = new URLClassLoader(new URL[]{new File(tools).toURI().toURL()}); Class virtualMachine = Class.forName("com.sun.tools.attach.VirtualMachine", true, loader); Class virtualMachineDescriptor = Class.forName("com.sun.tools.attach.VirtualMachineDescriptor", true, loader); Method getVMList = virtualMachine.getMethod("list", (Class[])null); Method attachToVM = virtualMachine.getMethod("attach", String.class); Method getAgentProperties = virtualMachine.getMethod("getAgentProperties", (Class[])null); Method getVMId = virtualMachineDescriptor.getMethod("id", (Class[])null); List allVMs = (List)getVMList.invoke(null, (Object[])null); for(Object vmInstance : allVMs) { String id = (String)getVMId.invoke(vmInstance, (Object[])null); if (id.equals(Integer.toString(pid))) { Object vm = attachToVM.invoke(null, id); Properties agentProperties = (Properties)getAgentProperties.invoke(vm, (Object[])null); String connectorAddress = agentProperties.getProperty(CONNECTOR_ADDRESS); if (connectorAddress != null) { return connectorAddress; } else { break; } } } } catch (Exception ignore) { } } return null; } }
最後更新:2017-04-03 18:52:08