[英]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.