|
外部アプリ起動がプチ簡単に 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) |
|