我正在尝试为通过 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 功能,通过使用 -J 选项向调用
javaws
程序指定以下变量(如果我使用 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 进程来执行此操作?
提前致谢。
补充说明
- 这适用于 Java 1.6+(不是 1.5)。
- 当我直接调用我的程序并通过命令行传递它们时,这些选项确实有效。
- 有些人提到直接指定 IP,使用 java.rmi.server.hostname=YOUR_IP。但是,当进程正常启动时,这似乎不需要,所以我认为它与 WebStart 场景无关。
- 我可以使用与 Attach API 的连接通过 PID 与 JConsole 或 JVisualVM 连接到进程,但最终产品不能依赖于此,因为它需要 JDK 或捆绑 tools.jar,我不认为有是开放的替代品。如果有,那实际上会容易得多,所以如果你知道,请告诉我。
更新:
实际上,当使用我最后一个带有显式的示例时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