| 
    
 
      外部アプリ起動がプチ簡単に ProcessBuilder | 
    ||||
 
  | 
    ||||
|   外部アプリの起動は Runtime#exec メソッドを使用すれば可能です。でも、なぜか外部アプリ起動用のクラスが Tiger では作られています。その名も ProcessBuilder。しかし、機能は全然変わりません。 なにが変わったかというと、使い方が簡単になったということなのです。 
  | 
    
 
  | 
    |||||||||||
|   変わらないといっていてもしょうがないので、使ってみましょう。 
 このサンプルは java を -version オプションで起動するものです。 
 ProcessBuilder クラスのコンストラクタの引数は、起動するプログラムとその引数です。コンストラクタの引数は可変長引数になっているので、プログラムの引数をいくつでも書くことができます。 プログラムの起動は start メソッドを使用します。start メソッドの戻り値は Process オブジェクトなので、後は Runtime#exec メソッドの時と同じになります。 ここで、Process オブジェクトから標準エラー出力を取っているのはバージョン情報がエラー出力に書きだされるからです。 実行すると、 
 となり、ちゃんと起動されていることが分かると思います。 せっかくなので環境変数をセットしてみましょう。 
 ProcessBuiderTest2 クラスは Sample クラスを起動します。Sample クラスは環境変数 "SAMPLE" を出力しているだけです。 
 ProcessBuilderTest2 は次のようになっています。 
 環境変数をセットするには、まず ProcessBuilder#environment メソッドで現在の環境変数の一覧を取得します。これは Map オブジェクトになっており、そのオブジェクトに追加、削除、更新を行うようにします。 単に Sample クラスだけを実行すると null と出力されますが、ProcessBuilderTest2 から起動すると sample と出力されます。 
 これ以外にも、directory メソッドでワーキングディレクトリを指定したり、command メソッドで起動するプログラムを変更することもできます。 
  | 
    
 
  | 
    ||||
|   ProcessBuilder クラスができた今、Runtime#exec メソッドはどうなっているのでしょうか。Runtime#exec メソッドは引数によって 6 種類ありますが、一番細かい制御を行うことのできる Runtime#exec(String[] cmdarray, String[] envp, File dir) の定義を見てみましょう。 
 なんのことはない ProcessBuilder クラスを使用しているようになっていました。 
  | 
    
 
  | 
    ||||
|   ようは ProcessBuilder クラスはリファクタリングして、扱いやすくしただけのようです。それでも、Runtime クラスがごちゃごちゃしているので、いいのかもしれません。 それよりも重要なのは、今まで Runtime#exec はいろいろとバグを含んでいたということです。これは Bug Parade の 4109888 Semantics of external process is not defined in JLS です。 もし、ProcessBuilder クラスとして書き直すことで、このバグが直っているのであれば、万々歳なのですが... beta 2 ではまだ Bugs Fixed in J2SE 1.5.0 Tiger にはのっていないようです。ちょっと、残念。 
 今回使用したサンプルはここからダウンロードできます。 
 (Jun. 2004)  | 
    
|  
       |