Java Webサービスから外部プロセスを起動する最良の方法は?
-
22-07-2019 - |
質問
Java Webサービスコードベース(BEA / Oracle Weblogic)を継承しており、Webサービスから外部バックグラウンドアプリケーションを起動/起動する必要があります。
すでに試しました:
ProcessBuilder pb = new ProcessBuilder(arg);
pb.start();
同様:
Runtime.exec(cmdString);
しかし、この方法でアプリケーションを起動すると、奇妙な動作が発生します(プロセスがまだアクティブであっても、起動したアプリケーションが動作を停止します。通常のコマンドラインから手動で実行すると、アプリケーションは正常に動作します)。
外部プロセスを起動するより良い方法はありますか?
編集:----------------------
問題を明らかにするのに役立つ追加情報があります。
- 開始しようとしているプロセスの完了には数時間かかるため、Webサービスでの完了の待機(
waitfor()
を使用)は理想的なシナリオではありません。 - はい、私たちがウェブサービスから開始しようとしているプロセスは、仲間のチームメンバーによって作成されました[手掛り:あなたの目が転がる...今]
成功したプロセスビルダーを使用してbashスクリプトを起動すると、外部アプリケーションがバックグラウンドプロセスとして起動されます("&" )。
#!/bin/bash
java -jar myApp.jar &
これは明らかに孤立したプロセスを作成しますが、少なくともアプリケーションは実行を続けます。
解決
簡単に言えば、起動したアプリケーションがSDTOUT / STDINに書き込みを行い、頻繁にフラッシュしない場合(Process.getErrorStream / Process.getInputStreamを参照)、バッファーがいっぱいになるとプロセスがブロックされます(本当に小さい、4KB以下)。
プロセスを開始する前にProcessBuilder.redirectErrorStream()を呼び出すことをお勧めします。その後、次の行に沿ってrun()メソッドでスレッドを作成します。
public void run() {
BufferedReader reader =
new BufferedReader(new InputStreamReader(process.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
}
他のヒント
「プロセスがまだアクティブであっても動作を停止する」ことにより」私はあなたが起動したアプリケーションからの出力を期待しているのに、何も得られないと思っていると思います。
次を使用して試してください:
ProcessBuilder pb = new ProcessBuilder(arg);
Process p = pb.start();
p.waitFor();
waitFor()は、必要に応じて、このProcessオブジェクトによって表されるプロセスが終了するまで、現在のスレッドを待機させます。
http:// java .sun.com / javase / 6 / docs / api / java / lang / Process.html#waitFor()
まず、これはWindowsで起こっていますか、それともLinuxで起こっていますか?また、起動されたアプリケーションは多かれ少なかれ何をするはずですか(スクリプトですか?バイナリですか?あなたのバイナリですか?)
編集
OK、そのため bash
スクリプトを( ProcessBuilder
を使用して)開始すると、新しいJVM( java -jar myApp.jar
)が生成されます動作します。
ProcessBuilder
を使用して新しいJVMを直接生成しようとするとどうなりますか?元々言った:
起動されたアプリケーションは動作を停止します
- 起動されたアプリケーションとは、「
jar myApp.jar」を意味します。直接呼び出された場合、中間の bash
スクリプトを介して されませんか? - Javaを直接起動しようとして、この新しいJVMが機能しなくなったときに、さまざまな
ProcessBuilder
メソッドに渡す正確かつ完全なパラメーター(およびその値)は何ですか? (例:注釈付きコードの提供) - * nixマシンに
lsof
をインストールした場合、実行時にファイル記述子2(FD
列を参照)に関連付けられているファイルが表示されます:lsof -p 1234
(1234
は" hung" JVMのプロセスID?)lsof
コマンドはこちら。 - 上記のステップ3で特定したファイルに追加されるもの(ファイル記述子2の場合)、コマンドを発行してから数秒後:
kill -QUIT 1234
(1234
は" hung" JVMのプロセスIDですか?)
プロセスの標準入出力を適切に処理していますか?標準の入力または出力がアプリケーションによって処理されていて、それを適切に処理していない場合、実行するプロセスはI / Oを待ってハングします。
これをテストする方法は、プログラムを実行し、標準入力、出力、エラーをファイルにリダイレクトするスクリプトを作成することです。次に、Webサービスアプリにプログラムの代わりにスクリプトを実行させます。プログラムがこの方法で完了するまで実行される場合、問題はプロセスの出力の処理です。
問題の原因は、プロセスを起動するスレッドが終了するか、要求が終了した後の何かであると推測しています。アプリケーション内に常にスレッドが1つ存在することを確認してください。他のスレッドから呼び出して、プロセスを開始することができます。