[英]How to use a JMX RMI agent in a WebStart process?
我正在尝试通过WebStart为应用程序启动器基于JMX的RMI连接器实现监视控件。
无论我从命令行或IDE启动应用程序时如何启动它们,连接器都可以正常工作。 但是,当我尝试通过使用javaws调用JNLP文件启动它检查时,一切都变了。
我尝试了几种方法:
使用内置的JMX功能,通过在JAVAWS_VM_ARGS中指定以下变量(文档说它应该在1.6中起作用,但是人们报告说它不起作用;如果我检查了结果过程中,它们似乎根本没有设置)使用附加API):
-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.local.only=true -Dcom.sun.management.jmxremote.port=SOME_PORT_HERE -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false
使用内置的JMX功能,通过在JNLP文件中指定以下变量(有人说这不起作用,实际上在我使用Attach API进行检查时似乎没有设置它们; JNLP设置了所有-权限):
<property name="com.sun.management.jmxremote.local.only" value="true" /> <property name="com.sun.management.jmxremote.port" value="SOME_PORT_HERE" /> <property name="com.sun.management.jmxremote.authenticate" value="false" /> <property name="com.sun.management.jmxremote.ssl" value="false" />
使用内置的JMX功能,通过在调用javaws
程序中使用-J选项指定以下变量(如果我使用Attach API检查它们,它们在结果过程中似乎根本没有设置):
-J-Dcom.sun.management.jmxremote -J-Dcom.sun.management.jmxremote.local.only=true -J-Dcom.sun.management.jmxremote.port=SOME_PORT_HERE -J-Dcom.sun.management.jmxremote.authenticate=false -J-Dcom.sun.management.jmxremote.ssl=false
使用具有以下代码的自定义JMXConnectorServer(仍然像以前的尝试一样拒绝连接,并显示“连接失败。重试?连接未成功。”):
try { final MBeanServer mbs = ManagementFactory.getPlatformMBeanServer(); final String jmxPort = System.getProperty("jmx.port"); if (jmxPort != null) { final int port = Integer.parseInt(jmxPort); System.out.println("settings JMX properties"); System.setProperty("java.rmi.server.randomIDs", "true"); Map<String, String> env = new HashMap<String, String>(); env.put("com.sun.management.jmxremote.ssl", "false"); env.put("com.sun.management.jmxremote.authenticate", "false"); env.put("com.sun.management.jmxremote.local.only", "true"); System.out.println("Creating Locate Registry"); LocateRegistry.createRegistry(port); System.out.println("Creating JMX Service URL"); JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://localhost:" + port + "/server"); System.out.println("Creating new JMX Connector Server"); JMXConnectorServer cs = JMXConnectorServerFactory.newJMXConnectorServer(url, env, mbs); cs.start(); } } catch (final RemoteException e) { e.printStackTrace(); } catch (final MalformedURLException e) { e.printStackTrace(); } catch (final IOException e) { e.printStackTrace(); }
我尝试使用以下JMXServiceURL与JConsole连接(最终,这将通过另一个程序来完成,但是我尝试从JConsole验证JMX服务是否正常运行):
service:jmx:rmi:///jndi/rmi://localhost:SOME_PORT_HERE/jmxrmi
有谁知道如何以编程方式执行此操作,或者如何将这些属性传递给WebStart-ed流程?
提前致谢。
更新:
实际上,当将我的最后一个示例与显式JMXConnectorServer
,我在WebStart进程启动时获得了NPE,其内容如下:
12:39:28,743 WARN [App] [trce] java.lang.NullPointerException
at org.jboss.security.jndi.LoginInitialContextFactory.getInitialContext(LoginInitialContextFactory.java:81)
at javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:667)
at javax.naming.InitialContext.getDefaultInitCtx(InitialContext.java:288)
at javax.naming.InitialContext.init(InitialContext.java:223)
at javax.naming.InitialContext.<init>(InitialContext.java:197)
at javax.management.remote.rmi.RMIConnectorServer.bind(RMIConnectorServer.java:619)
at javax.management.remote.rmi.RMIConnectorServer.start(RMIConnectorServer.java:412)
// line invoking .start() on the JMXConnectorServer's instance
正如在问题注释中与jtahlborn讨论的那样,我们发现这确实是针对应用程序设置的。
使JMX在WebStart-ed应用程序中工作需要解决一些陷阱,并且对使用多个JNDI上下文工厂也有一些影响。
在这种特殊情况下,应用程序在启动和填充配置设置时读取了jndi.properties
,因此,JBoss JNDI上下文工厂已经位于WebStart-ed应用程序的入口点/主类的静态块的调用点处。 。
由于这些JNDI属性对于程序的其余部分是必需的,因此解决方案就是在以编程方式创建JMXServerConnector
时简单地覆盖这些属性。
这是一个例子:
@SuppressWarnings("serial")
private static Properties initProperties() {
return (new Properties() {{
// overrides for the JNDI factory
// mostly changing the INITIAL_CONTEXT_FACTORY from:
// "org.jboss.security.jndi.JndiLoginInitialContextFactory"
// to:
put(Context.INITIAL_CONTEXT_FACTORY,
"org.jnp.interfaces.NamingContextFactory");
put(Context.PROVIDER_URL, "jnp://localhost/");
// Required JMX properties and other things ...
// YMMV of course, these were for my current settings
put("java.rmi.server.randomIDs", "true");
put("java.rmi.server.hostname", host); // host needs to be an IP
put("com.sun.management.jmxremote.ssl", "false");
put("com.sun.management.jmxremote.authenticate", "false");
put("com.sun.management.jmxremote.local.only", "true");
put("com.sun.management.jmxremote.port", String.valueOf(port));
}});
}
和:
// error handling left out for clarity
private static void startJMXAgent() throws TheWorld {
Registry reg = LocateRegistry.createRegistry(port);
JMXConnectorServer cs =
JMXConnectorServerFactory.newJMXConnectorServer(
new JMXServiceURL(
"service:jmx:rmi://" + host + ":" + port + "/" +
"jndi/rmi://" + host + ":" + port + "/" +
servicename
),
initProperties(),
ManagementFactory.getPlatformMBeanServer()
);
cs.start();
}
注意:我想您可能会采取其他方法,并在命令行或JNLP文件中覆盖这些属性,然后将它们重置为以后上下文所需的内容。 但是,这不适合这里的用例,因此我没有真正研究它。
尝试在Windows上的命令行中设置以下参数
设置JAVAWS_VM_ARGS = -Dcom.sun.management.jmxremote.port = 9400 -Dcom.sun.management.jmxremote.authenticate = false -Dcom.sun.management.jmxremote.ssl = false
然后从同一命令提示符启动jnlp文件。 它为我工作。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.