【发布时间】:2012-07-26 13:46:19
【问题描述】:
我正在尝试为通过 WebStart 的应用程序启动器实现基于 JMX 的 RMI 连接器的监视控制。
从命令行或 IDE 启动应用程序时,无论我如何启动它们,连接器都能正常工作。但是,当我通过使用 javaws 调用 JNLP 文件启动它时尝试检查它时,一切都变了。
我尝试了几种方法:
-
使用内置的 JMX 功能,通过在 JAVAWS_VM_ARGS 中指定以下变量(文档说它应该在 1.6 中工作,但人们报告它没有;在结果过程中似乎根本没有设置它们,如果我使用 Attach 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
【问题讨论】:
-
我知道您不想要“您是否尝试过”cmets,但对于最后一个示例,您是否尝试使用类似以下网址:
"service:jmx:rmi://localhost:" + port + "/jndi/rmi://localhost:" + port + "/server"。另外,我假设您的 webstart 应用程序被授予所有权限? -
@jtahlborn:也不起作用。我已经在 JNLp 中授予了所有权限,是的(见第 2 点)。
-
我认为最后一个解决方案可能有效,问题似乎是您配置的默认初始上下文是 jboss 上下文。您需要制作不使用 jboss 上下文的 rmi 东西。可能需要传入诸如“com.sun.jndi.rmi.registry.RegistryContextFactory”之类的初始上下文工厂,请参阅docs.oracle.com/javase/1.5.0/docs/guide/jndi/jndi-rmi.html
-
@jtahlborn:是的,这看起来确实是个问题。不幸的是,我需要设置这个 InitialContext。但是,这让我想起了我不久前遇到的一个类似问题(完全不同且不相关的上下文),我确实设法交换了初始上下文。这可能是在这里尝试的东西。如果我对此线程感兴趣,我会看看它的进展并回来:) 感谢您的帮助。
-
漂亮,我很高兴你让它工作了。我相信其他人会欣赏这些细节。
标签: java jmx jnlp java-web-start