4

別のJavaアプリケーションを起動するJavaアプリケーションがあります。ランチャーにはウォッチドッグタイマーがあり、2番目のVMから定期的に通知を受け取ります。ただし、通知が受信されない場合は、2番目の仮想マシンを強制終了し、ランチャーが追加のクリーンアップアクティビティを実行します。

問題は、Javaのみを使用してこれを行う方法はありますか?これまでのところ、この操作を実行するにはいくつかのネイティブメソッドを使用する必要があり、それはどういうわけか醜いです。

ありがとう!

4

9 に答える 9

6

何か不足しているかもしれませんが、返されたオブジェクトのdestroy()メソッドを呼び出すことはできませんか?ProcessRuntime.exec()

于 2008-09-15T15:24:49.043 に答える
3

java.lang.Processを使用して、必要なことを行うことができます。ネストされたプロセスを作成し、Process インスタンスへの参照を取得したら、その標準出力およびエラー ストリームへの参照を取得できます。それらを定期的に監視し、プロセスを閉じたい場合は .destroy() を呼び出すことができます。全体は次のようになります。

Process nestedProcess = new ProcessBuilder("java mysubprocess").start();
InputStream nestedStdOut = nestedProcess.getInputStream(); //kinda backwards, I know
InputStream nestedStdErr = nestedProcess.getErrorStream();
while (true) {
    /*
       TODO: read from the std out or std err (or get notifications some other way)
       Then put the real "kill-me" logic here instead of if (false)
    */
    if (false) {
        nestedProcess.destroy();
        //perform post-destruction cleanup here
        return;
    }

    Thread.currentThread().sleep(1000L); //wait for a bit
}

お役に立てれば、

ショーン

于 2008-09-15T15:42:10.263 に答える
2

これを行う通常の方法はProcess.destroy()... を呼び出すことですが、* nix で sun JVM を使用する場合、プロセスを終了することが保証されていない SIGTERM にマップを破棄するため、これは不完全な解決策です (そのためには SIGKILL も必要です)。最終的な結果として、Java を使用して実際のプロセス管理を行うことはできません。

この問題に関する未解決のバグがいくつかあります。 リンク テキストを参照してください。

于 2008-09-17T08:30:36.137 に答える
2

System.exit() を呼び出す 2 番目の JVM で (バーラップ、ヘシアンなどを介して) サービスを公開し、ウォッチドッグ JVM からそれを使用することもできます。2 番目の JVM が定期的な通知の送信を停止したときにのみシャットダウンする場合は、サービス呼び出しに応答する状態にない可能性があります。

おそらく、java.lang.Runtime.exec() を使用してシェル コマンドを呼び出すのが最善の方法です。

于 2008-09-15T15:26:00.863 に答える
1

OK要点のひねりは次のとおりです。

Process API を使用して 2 番目の仮想マシンを閉じていましたが、うまくいきませんでした。

その理由は、2 つ目のアプリケーションが Eclipse RCP アプリケーションであり、付属の eclipse.exe ランチャーを使用して起動したためです。

ただし、これは、プロセス API の destroy() メソッドが eclipse.exe プロセスをターゲットにすることを意味します。このプロセスを強制終了すると、Java プロセスは無傷のままになります。そこで、ここにいる私の同僚の 1 人が、適切なアプリケーションを強制終了する小さなアプリケーションを作成しました。

したがって、プロセス API を使用する (そして冗長な中間ステップを削除する) ための解決策の 1 つは、Eclipse ランチャーを使用せずに、最初の仮想マシンにすべての機能を複製させることです。

私は仕事に行かなければならないと思います。

于 2008-09-17T07:17:22.363 に答える
1

java.lang.ProcessプロセスがwaitFor()終了するのを待つdestroy()メソッドと、サブプロセスを強制終了するメソッドがあります。

于 2008-09-15T15:47:58.707 に答える
0

java.lang.Runtime.execそれとシェルコマンドを実行できるはずです。

于 2008-09-15T15:14:01.673 に答える
0

Java コードで実行時にプラットフォームを検出し、プラットフォームの kill プロセス コマンドを起動することができます。これは、実際に現在のソリューションを改良したものです。

ProcessBuilder APIを使用している場合は、Process.destroy ()もあります。

于 2008-09-15T15:17:24.537 に答える
0

正確にはプロセス管理ではありませんが、起動している Java 仮想マシンで rmi サーバーを起動し、必要なクリーンアップを実行して System.exit() を呼び出すメソッドにリモートインスタンスをバインドできます。最初の vm は、そのリモート メソッドを呼び出して 2 番目の vm をシャットダウンできます。

于 2008-09-15T15:29:14.837 に答える