1

JUnit を使用して、外部サーバー (tomcat) の実行を必要とする多くのテストを実行しています。現在、次のコードを使用して tomcat を起動しています。

    Thread thread = new Thread(new Runnable() {
        @Override
        public void run() {
            try {
                Runtime.getRuntime().exec("{path to tomcat}/bin/startup.bat");
            } catch (IOException exception) {
            }
        }
    });
    thread.setDaemon(true);

この問題は、すべてのテストが完了すると発生し、Tomcat が閉じられるのを待って JVM がハングします。Tomcat を手動で閉じると、JVM は期待どおりに閉じます。

すべてのテストが完了すると (他のすべてのスレッドが終了すると)、JVM がブロックされずにシャットダウンされるように tomcat を実行する方法はありますか?

4

3 に答える 3

1

startup.batこの場合、バッチ スクリプトの実行に使用したスレッドを終了しても、Tomcat サーバーは終了しません。ソリューション:


簡単な説明:

shutdown.battomcat を停止するには、実行する必要があります。


長い説明:

startup.bat行を見る56と、スクリプトがコマンドを実行していることがわかりますcall "%EXECUTABLE%" start %CMD_LINE_ARGS%%EXECUTABLE%行に設定されています38: set "EXECUTABLE=%CATALINA_HOME%\bin\catalina.bat". を見るとcatalina.bat、いくつかの標準変数を設定して引数をチェックした後、行242( if ""%1"" == ""start"" goto doStart) で にジャンプし:doStart、行にある にジャンプし279て、引数にシフト マジックを実行し、それに設定_EXECJAVAするstart [...]と、最終的に 内にあるものを実行し%_EXECJAVA%ます。開始する場合、これはstartコマンドに関係するものになります。コマンドのこのドキュメントstartからわかるように:

プログラム、コマンド、またはバッチ スクリプトを開始します (新しいウィンドウで開きます)。

したがって、基本的に、開始しているプロセスはスクリプトを実行することです。スクリプトは別のプログラムを開始し、終了します。これにより、プロセスが自動的に終了し、スレッドが終了します。実際、Tomcat を直接制御することはできませんbin。ディレクトリ内のスクリプトしか使用できません。


結論:

したがって、プログラムの最後で次のことを行うのは簡単なはずです (シャットダウン フックを使用することもできます)。

    Thread thread = new Thread(new Runnable() {
        @Override
        public void run() {
            try {
                Runtime.getRuntime().exec("{path to tomcat}/bin/shutdown.bat");
            } catch (IOException exception) {
            }
        }
    });

したがって、実行startup.batして tomcat を開始しshutdown.bat、終了します。

古い質問への回答で申し訳ありません。

于 2015-03-30T14:38:48.590 に答える
0

プロセスから入力ストリームを空にする必要があります。そうしないと、バッファサイズがいっぱいになると「奇妙な」動作をします。p.exec() によって返されるプロセスであると仮定します。

BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream()));
String in;
while ((in = br.readLine()) != null);

while ループを変更して { } を追加し、必要に応じて tomcat の出力を実際に出力することもできますが、実際に必要なのはバッファーを空にすることだけです。

于 2013-08-23T06:56:22.237 に答える