41

これは私自身の以前の質問のフォローアップであり、これを尋ねるのはちょっと恥ずかしいです...しかし、とにかく、システムに依存しない方法でスタンドアロンのJavaプログラムから2番目のJVMをどのように起動しますか? また、たとえば JAVA_HOME などの環境変数に依存することなく、現在実行中のものとは異なる JRE を指す可能性があります。実際には動作しますが、少しぎこちなく感じる次のコードを思いつきました。

public static void startSecondJVM() throws Exception {
    String separator = System.getProperty("file.separator");
    String classpath = System.getProperty("java.class.path");
    String path = System.getProperty("java.home")
                + separator + "bin" + separator + "java";
    ProcessBuilder processBuilder = 
                new ProcessBuilder(path, "-cp", 
                classpath, 
                AnotherClassWithMainMethod.class.getName());
    Process process = processBuilder.start();
    process.waitFor();
}

また、現在実行中の JVM は、2 番目の JVM が知らない他のパラメーター (-D、-X...、...) で開始されている可能性があります。

4

4 に答える 4

6

答えは「Yes」だと思います。これはおそらく、システムに依存しないコードを使用して Java で実行できるのと同じくらい優れています。ただし、これでさえ比較的システムに依存しないことに注意してください。たとえば、一部のシステムでは次のようになります。

  1. JAVA_HOME 変数が設定されていない可能性があります。
  2. JVM の起動に使用されるコマンド名が異なる可能性があります (たとえば、Sun JVM でない場合)。
  3. コマンド ライン オプションは異なる場合があります (たとえば、Sun JVM でない場合)。

(2 番目の) JVM を起動する際に最大の移植性を目指していた場合、ラッパー スクリプトを使用することになると思います。

于 2009-08-05T00:06:41.100 に答える
5

セカンダリ プロセスを開始するときに、常にまったく同じパラメーター、クラスパスなど (特に -X のようなもの - たとえば、子が親と同じヒープ設定を必要とする理由など) を常に使用する必要があるかどうかはわかりません。

何らかの外部構成を使用して、これらのプロパティを子に対して定義することをお勧めします。もう少し手間がかかりますが、最終的には柔軟性が必要になると思います。

可能な構成設定の範囲を確認するには、Eclipse の「実行構成」設定を確認してください。そこにはかなりの数のタブに相当する構成があります。

于 2009-08-04T20:23:05.527 に答える
5

コードが現在実行されている Java 実行可能ファイル (つまり、質問のサンプル コードの「パス」変数) を見つけるには、Apache ant 内に役立つユーティリティ メソッドがあります。コードを ant でビルドする必要はありません。この 1 つのメソッドのために、ant をライブラリとして使用するだけです。

それは:

org.apache.tools.ant.util.JavaEnvUtils.getJreExecutable("Java")

他の人が言及したさまざまな JVM ベンダーの特殊なケースを処理します。(そして、そのソースコードを見ると、想像以上に特殊なケースがあります。)

それはant.jarにあります。ant は Apache ライセンスの下で配布されているので、問題なく好きなように使用できることを願っています。

于 2011-07-27T22:55:02.267 に答える