簡體   English   中英

如何在WebStart流程中使用JMX RMI代理?

[英]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流程?

提前致謝。

補充筆記

  • 這是針對Java 1.6+(而非1.5)的。
  • 這些選項工作時,我直接調用我的程序,並通過命令行傳遞它們。
  • 有人提到使用java.rmi.server.hostname = YOUR_IP直接指定IP。 但是,正常啟動該過程時似乎並不需要,因此我認為這與WebStart場景無關。
  • 我可以使用帶有Attach API的連接來通過JConsole或JVisualVM通過PID連接到進程,但是最終產品不能依賴於此,因為它需要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

正如在問題注釋中與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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM