3

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機能を使用し、呼び出し元の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プロセスに渡す方法を誰かが知っていますか?

前もって感謝します。

その他の注意事項

  • これはJava1.6以降(1.5ではない)用です。
  • これらのオプション、プログラムを直接呼び出してコマンドラインから渡すときに機能します。
  • java.rmi.server.hostname = YOUR_IPを使用して、IPを直接指定することに言及した人もいます。ただし、プロセスが正常に開始される場合、これは必要ないように思われるため、WebStartシナリオには関連しないと思います。
  • Attach APIとの接続を使用して、JConsoleまたはJVisualVMを使用してPIDでプロセスに接続できますが、JDKまたはt​​ools.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
4

2 に答える 2

0

質問のコメントでjtahlbornと話し合ったように、これはアプリケーションのセットアップに本当に固有であることがわかりました。

JMXをWebStart-edアプリケーションで機能させるために対処すべきいくつかの落とし穴があり、複数のJNDIコンテキストファクトリの使用にもいくつかの影響があります。

この特定のケースでは、アプリケーションはjndi.properties起動時の読み取りと設定設定の設定を行っていたため、JBossJNDIコンテキストファクトリはすでに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ファイルでこれらのプロパティをオーバーライドしてから、後のコンテキストで必要なものにリセットできると思います。ただし、これはここでのユースケースに適合しなかったため、実際には調べませんでした。

于 2012-04-23T13:26:17.293 に答える
0

Windowsのコマンドラインから次の引数を設定してみてください

set JAVAWS_VM_ARGS = -Dcom.sun.management.jmxremote.port = 9400 -Dcom.sun.management.jmxremote.authenticate = false -Dcom.sun.management.jmxremote.ssl = false

次に、同じコマンドプロンプトからjnlpファイルを起動します。それは私のために働いた。

于 2012-07-26T05:46:19.473 に答える