[英]How to use a JMX RMI agent in a WebStart process?
I am trying to implement a monitoring control based on an RMI connector for JMX, for an application launcher via WebStart. 我正在尝试通过WebStart为应用程序启动器基于JMX的RMI连接器实现监视控件。
The connectors work fine no matter how I start them when the application is started from the command-line or IDE. 无论我从命令行或IDE启动应用程序时如何启动它们,连接器都可以正常工作。 However, everything goes south when I try to inspect it when it's been launched by invoking the JNLP file with javaws. 但是,当我尝试通过使用javaws调用JNLP文件启动它检查时,一切都变了。
I have tried several approaches: 我尝试了几种方法:
using the built-in JMX features, by specifying the following variables in JAVAWS_VM_ARGS (docs say it should work in 1.6, but people report it doesn't; they don't appear to be set at all in the resulting process, if I inspect it using the Attach API): 使用内置的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
using the built-in JMX features, by specifying the following variables in the JNLP file (some say this shouldn't work, and indeed they don't seem to be set when I inspect with the Attach API; the JNLP is set with all-permissions as well): 使用内置的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" />
using the built-in JMX features, by specifying the following variables using -J options to the calling javaws
program (they don't appear to be set at all in the resulting process, if I inspect it using the Attach API): 使用内置的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
using a custom JMXConnectorServer with the following code (connection is still refused as with the previous attempts, with "Connection Failed. Retry? The connection did not succeed."): 使用具有以下代码的自定义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(); }
I try to connect with JConsole (ultimately, this will be done from another program, but I try from JConsole to verify the JMX service is running correctly) with this JMXServiceURL: 我尝试使用以下JMXServiceURL与JConsole连接(最终,这将通过另一个程序来完成,但是我尝试从JConsole验证JMX服务是否正常运行):
service:jmx:rmi:///jndi/rmi://localhost:SOME_PORT_HERE/jmxrmi
Does anyone have any idea how to do this, either programmatically or how to get these properties passed to the WebStart-ed process? 有谁知道如何以编程方式执行此操作,或者如何将这些属性传递给WebStart-ed流程?
Thanks in advance. 提前致谢。
Update: 更新:
Actually, when using my last example with an explicit JMXConnectorServer
, I get an NPE at the launch-time of the WebStart process, with: 实际上,当将我的最后一个示例与显式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
As discussed with jtahlborn in the question's comment, we worked out that this was really specific to the application's setup. 正如在问题注释中与jtahlborn讨论的那样,我们发现这确实是针对应用程序设置的。
There are some pitfalls to address to make JMX work for WebStart-ed applications, and there's also some implications to the use of multiple JNDI context factories. 使JMX在WebStart-ed应用程序中工作需要解决一些陷阱,并且对使用多个JNDI上下文工厂也有一些影响。
In this particular case, the application had a jndi.properties
read on startup and populating configuration settings, so a JBoss JNDI context factory was already even at the call point of the static block of the WebStart-ed application's entry-point / main-class. 在这种特殊情况下,应用程序在启动和填充配置设置时读取了jndi.properties
,因此,JBoss JNDI上下文工厂已经位于WebStart-ed应用程序的入口点/主类的静态块的调用点处。 。
As these JNDI properties were necessary for the rest of the program, the solution is simply to override these properties when creating the JMXServerConnector
programmatically. 由于这些JNDI属性对于程序的其余部分是必需的,因此解决方案就是在以编程方式创建JMXServerConnector
时简单地覆盖这些属性。
Here's an example: 这是一个例子:
@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));
}});
}
and: 和:
// 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();
}
Note: I assume you could probably do it the other way around and override these properties on the command-line or in the JNLP file, and then reset them to whatever is needed for later contexts. 注意:我想您可能会采取其他方法,并在命令行或JNLP文件中覆盖这些属性,然后将它们重置为以后上下文所需的内容。 However, this didn't fit the use case here so I didn't really look into it. 但是,这不适合这里的用例,因此我没有真正研究它。
try setting following argument from command line on windows 尝试在Windows上的命令行中设置以下参数
set JAVAWS_VM_ARGS=-Dcom.sun.management.jmxremote.port=9400 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false 设置JAVAWS_VM_ARGS = -Dcom.sun.management.jmxremote.port = 9400 -Dcom.sun.management.jmxremote.authenticate = false -Dcom.sun.management.jmxremote.ssl = false
and then start the jnlp file from that same command prompt. 然后从同一命令提示符启动jnlp文件。 It worked for me. 它为我工作。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.