我有一个程序,它需要动态(即在运行时)打开一个可用的套接字并在其上启动一个JMX代理.此JMX参数在Java代码中设置,而不是通过命令行设置.这很好用.此后,需要远程通过Java Visual VM监视(即发出JMX命令等)
该程序中的RMI服务器代理处于以下所述的开箱即用管理行为:http: //download.oracle.com/javase/6/docs/technotes/guides/management/agent.html
我的问题可以概括为:如何通过Java代码将这些命令行属性设置为系统级别,以便可以使用远程分析?
-Dcom.sun.management.jmxremote.port=1234
Run Code Online (Sandbox Code Playgroud)
如果通过命令行设置"jmxremote.port"和其他参数,则远程监视工作正常.我试图通过Java而不是通过命令行找到一种方法.
程序无法通过命令行指定端口,因为必须在运行时计算出新的可用端口.
该过程需要远程监控,并且在本地工作正常.如果未在命令行中指定以下参数,则Java Visual VM不会连接到该进程.
-Dcom.sun.management.jmxremote.port=1234
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false
-Djava.rmi.server.hostname=10.0.0.128
Run Code Online (Sandbox Code Playgroud)
我试过了.
System.setProperty("com.sun.management.jmxremote.port",Integer.toString(port));
Run Code Online (Sandbox Code Playgroud)
这是在启动JMXConnectorServer之前在程序中完成的第一件事.不幸的是,它没有被认可.只有运行时属性(即通过命令行指定由Java Visual VM识别JMX连接).
还遇到了可以从java集合类中提取属性的方法但无法到达如何跟踪属性"com.sun.management.jmxremote.port ="
public static void setEnv(Map<String, String> newenv) throws Exception {
Class[] classes = Collections.class.getDeclaredClasses();
Map<String, String> env = System.getenv();
for(Class cl : classes) {
if("java.util.Collections$UnmodifiableMap".equals(cl.getName())) {
Field field = cl.getDeclaredField("m");
field.setAccessible(true);
Object obj = field.get(env);
Map<String, String> map = (Map<String, String>) obj;
//map.clear();
map.putAll(newenv);
}
}
}
Run Code Online (Sandbox Code Playgroud)
任何帮助,将不胜感激!
Mar*_*ler 10
kbec的答案显示了方式,但对我不起作用 - 但是通过查看这篇文章,我能够修改它并获得一个有效的解决方案.
public static String loadJMXAgent(int port) throws IOException,
AttachNotSupportedException, AgentLoadException,
AgentInitializationException {
String name = ManagementFactory.getRuntimeMXBean().getName();
VirtualMachine vm = VirtualMachine.attach(name.substring(0,
name.indexOf('@')));
String lca = vm.getAgentProperties().getProperty(
"com.sun.management.jmxremote.localConnectorAddress");
if (lca == null) {
Path p = Paths.get(System.getProperty("java.home")).normalize();
if (!"jre".equals(p.getName(p.getNameCount() - 1).toString()
.toLowerCase())) {
p = p.resolve("jre");
}
File f = p.resolve("lib").resolve("management-agent.jar").toFile();
if (!f.exists()) {
throw new IOException("Management agent not found");
}
String options = String.format("com.sun.management.jmxremote.port=%d, " +
"com.sun.management.jmxremote.authenticate=false, " +
"com.sun.management.jmxremote.ssl=false", port);
vm.loadAgent(f.getCanonicalPath(), options);
lca = vm.getAgentProperties().getProperty(
"com.sun.management.jmxremote.localConnectorAddress");
}
vm.detach();
return lca;
}
Run Code Online (Sandbox Code Playgroud)
这在Eclipse中可行,但是在命令行中使用它是另一回事 - 这里有一些讨论为什么在Linux上使用Java Attach API会失败?(即使maven构建完成) 但我发现在我的类路径中添加$ JAVA_HOME/lib/tools.jar解决了这个问题.
| 归档时间: |
|
| 查看次数: |
24641 次 |
| 最近记录: |