java.lang.Process APIガイド

1前書き

このチュートリアルでは、 Process API ** について詳しく見ていきます。

Process を使用してシェルコマンドを実行する方法をもっと浅く見たい場合は、以前のチュートリアルhttps://www.baeldung.com/run-shell-command-in-java[here]を参照してください。

それが指すプロセスは実行中のアプリケーションです。 Process クラスは、出力の抽出、入力の実行、ライフサイクルの監視、終了ステータスの確認、および破棄(強制終了)など、これらのプロセスと対話するためのメソッドを提供します。

2 Javaプログラムをコンパイルおよび実行するための Process クラスの使用

Process APIを使用して別のJavaプログラムをコンパイルして実行する例を見てみましょう。

@Test
public void whenExecutedFromAnotherProgram__thenSourceProgramOutput3() throws IOException {

    Process process = Runtime.getRuntime()
      .exec("javac -cp src src\\main\\java\\com\\baeldung\\java9\\process\\OutputStreamExample.java");
    process = Runtime.getRuntime()
      .exec("java -cp src/main/java com.baeldung.java9.process.OutputStreamExample");
    BufferedReader output = new BufferedReader(new InputStreamReader(process.getInputStream()));
    int value = Integer.parseInt(output.readLine());

    assertEquals(3, value);
}

したがって、既存のJavaコード内でJavaコードを実行するアプリケーションは事実上無限である。

3作成プロセス

当社のJavaアプリケーションは、当社のコンピュータシステム内で実行されている、オペレーティングシステムの制限に対して主観的なあらゆるアプリケーションを呼び出すことができます。

そのため、アプリケーションを実行できます。 Process APIを利用して実行できるさまざまなユースケースが何かを見てみましょう。

ProcessBuilder クラスを使用すると、アプリケーション内にサブプロセスを作成できます。

Windowsベースのメモ帳アプリケーションを開くデモを見てみましょう。

ProcessBuilder builder = new ProcessBuilder("notepad.exe");
Process process = builder.start();

4破壊プロセス

Process は、サブプロセスまたはプロセスを破棄するメソッドも提供します。 しかし、アプリケーションが強制終了される方法はプラットフォームによって異なります

さまざまなユースケースを見てみましょう。

4.1. 参照によるプロセスの破棄

Windows OSを使用していて、メモ帳アプリケーションを起動して破棄したいとしましょう。

以前と同様に、 ProcessBuilder クラスと start() メソッドを使用して、メモ帳アプリケーションのインスタンスを作成できます。

その後、 Process オブジェクトの destroy() メソッドを呼び出します。

** 4.2. IDによるプロセスの破棄

**

私たちのアプリケーションによって作成されないかもしれない私たちのオペレーティングシステム内で実行されているプロセスを殺すこともできます。

オペレーティングシステムを不安定にさせる可能性がある重要なプロセスを無意識のうちに破壊する可能性があるため、これを行う際は注意が必要です。

まずタスクマネージャをチェックして現在実行中のプロセスのプロセスIDを見つけ、pidを見つけます。

例を見てみましょう。

Optional<ProcessHandle> optionalProcessHandle = ProcessHandle.of(5232);
optionalProcessHandle.ifPresent(processHandle -> processHandle.destroy());

4.3. プロセスを強制的に破棄する

destroy() メソッドを実行すると、この記事の前半で見たようにサブプロセスは強制終了されます。

  • destroy() が機能しない場合は、 destroyForcibly() のオプションがあります。**

常に destroy() メソッドから始めなければなりません。その後、 isAlive() を実行することによってサブプロセスのクイックチェックを実行できます。

trueが返された場合は、 destroyForcibly() を実行してください。

ProcessBuilder builder = new ProcessBuilder("notepad.exe");
Process process = builder.start();
process.destroy();
if (process.isAlive()) {
    process.destroyForcibly();
}

** 5プロセスが完了するのを待っています

**

また、2つのオーバーロードされたメソッドがあり、それによってプロセスの完了を待つことができます。

** 5.1. を待つ()

**

このメソッドが実行されると、サブプロセスが終了しない限り、現在の実行プロセススレッドをブロック待ち状態にします。

例を見てみましょう。

ProcessBuilder builder = new ProcessBuilder("notepad.exe");
Process process = builder.start();
assertThat(process.waitFor() >= 0);

現在のスレッドが実行を継続するための上記の例から、サブプロセススレッドが終了するのを待ち続けるでしょう。サブプロセスが終了すると、現在のスレッドは実行を続けます。

** 5.2. waitfor(long timeOut、TimeUnit time)

**

このメソッドが実行されると、サブプロセスが終了したりタイムアウトしたりしない限り、現在の実行プロセススレッドはブロック待ち状態になります。

例を見てみましょう。

ProcessBuilder builder = new ProcessBuilder("notepad.exe");
Process process = builder.start();
assertFalse(process.waitFor(1, TimeUnit.SECONDS));

現在のスレッドが実行を継続するための上記の例からわかるように、サブプロセススレッドが終了するのを待つか、または指定された時間間隔が経過したかどうかを継続します。

このメソッドが実行されると、サブプロセスが終了した場合はtrue、サブプロセスが終了する前に待機時間が経過した場合はfalseのブール値が返されます。

** 6. exitValue()

**

このメソッドが実行されると、現在のスレッドはサブプロセスが終了または破棄されるのを待ちませんが、サブプロセスが終了されない場合は IllegalThreadStateException がスローされます。

  • サブプロセスが正常に終了した場合の別の方法は、プロセスの終了値になります。

任意の正の整数です。

サブプロセスが正常に終了したときに exitValue() メソッドが正の整数を返す場合の例を見てみましょう。

@Test
public void
  givenSubProcess__whenCurrentThreadWillNotWaitIndefinitelyforSubProcessToEnd__thenProcessExitValueReturnsGrt0()
  throws IOException {
    ProcessBuilder builder = new ProcessBuilder("notepad.exe");
    Process process = builder.start();
    assertThat(process.exitValue() >= 0);
}

** 7. 生きている()

**

プロセスが生きているかどうかにかかわらず主観的なビジネス処理を実行したい場合。

プロセスが生きているかどうかを調べるために簡単なチェックを実行できます。

簡単な例を見てみましょう。

ProcessBuilder builder = new ProcessBuilder("notepad.exe");
Process process = builder.start();
Thread.sleep(10000);
process.destroy();
assertTrue(process.isAlive());

8プロセスストリームの処理

デフォルトでは、作成されたサブプロセスにはその端末またはコンソールがありません。その標準I/O(つまり、stdin、stdout、stderr)操作はすべて親プロセスに送信されます。それにより、親プロセスはこれらのストリームを使用してサブプロセスに入力を供給し、サブプロセスから出力を取得できます。

その結果、サブプロセスの入力/出力を制御できるため、これによって非常に大きな柔軟性が得られます。

** 8.1. getErrorStream()

**

興味深いことに、サブプロセスから生成されたエラーを取得してその上でビジネス処理を実行できます。

その後、要件に基づいて特定の業務処理チェックを実行できます。

例を見てみましょう。

@Test
public void givenSubProcess__whenEncounterError__thenErrorStreamNotNull() throws IOException {
    Process process = Runtime.getRuntime().exec(
      "javac -cp src src\\main\\java\\com\\baeldung\\java9\\process\\ProcessCompilationError.java");
    BufferedReader error = new BufferedReader(new InputStreamReader(process.getErrorStream()));
    String errorString = error.readLine();
    assertNotNull(errorString);
}

** 8.2. getInputStream()

**

サブプロセスによって生成された出力を取得して親プロセス内で消費することで、プロセス間で情報を共有することもできます。

@Test
public void givenSourceProgram__whenReadingInputStream__thenFirstLineEquals3() throws IOException {
    Process process = Runtime.getRuntime().exec(
      "javac -cp src src\\main\\java\\com\\baeldung\\java9\\process\\OutputStreamExample.java");
    process = Runtime.getRuntime()
      .exec("java -cp  src/main/java com.baeldung.java9.process.OutputStreamExample");
    BufferedReader output = new BufferedReader(new InputStreamReader(process.getInputStream()));
    int value = Integer.parseInt(output.readLine());

    assertEquals(3, value);
}

** 8.3. _ge _ tOutputStream() __

**

親プロセスからサブプロセスに入力を送ることができます。

Writer w = new OutputStreamWriter(process.getOutputStream(), "UTF-8");
w.write("send to child\n");

8.4. プロセスストリームのフィルタ

選択的に実行されているプロセスと対話することは、完全に有効なユースケースです。

Process は、特定の述語に基づいて実行中のプロセスを選択的にフィルタリングする機能を提供します。

その後、この選択的なプロセスセットで業務を実行できます。

@Test
public void givenRunningProcesses__whenFilterOnProcessIdRange__thenGetSelectedProcessPid() {
    assertThat(((int) ProcessHandle.allProcesses()
      .filter(ph -> (ph.pid() > 10000 && ph.pid() < 50000))
      .count()) > 0);
}

9結論

Process は、オペレーティングシステムレベルの対話のための強力なクラスです。

端末コマンドの起動、およびアプリケーションの起動、監視、強制終了

Java 9 Process APIの詳細については、https://www.baeldung.com/java-9-process-api[ここ]を参照してください。

いつものように、あなたはソースhttps://github.com/eugenp/tutorials/tree/master/core-java-9/src/main/java/com/baeldung/java9/process[over Github]を見つけるでしょう。

前の投稿:JavaでのInfinispanのガイド
次の投稿:Java Weekly、Issue 212