野狐消暇録

所感を記す

外部プログラムの呼び出しの話

Javaから外部プログラムを呼び出すための手順をまとめた記事をQiitaに書いて残す事にした。

qiita.com

この記事を書いたのには理由がある。

あるプログラムから、別の言語や環境のプログラムを呼び出すのは難しい事が多く、いつも苦労してきた。しかし、先日Javaから外部のプログラムを呼び出す処理を書いた所、思いの外容易に書く事ができた。そこで、この経験を纏めて書き残そうと思い、上述のQiitaの記事を書いたのである。

 

外部プログラムの呼び出しには、苦労した経験がある。

例えば、昔、Windowsのバッチファイルを使った事があった。

バッチファイルから別のバッチファイルを呼び出したのだが、ブロッキングしてくれず、平行して実行されてしまった。何かのコマンドだと、逐次実行されると聞いて試したのだが、なぜか駄目だったのだ。

他にも、外部プログラムの実行結果を呼び出し元で取得できなかったり、色々と難しい事が起こりがちである。

元々、ひとつのプログラムで実行したいと思っていて、呼び出し元の言語でうまくいかないから、外部プログラムを使う。そうすると、呼び出し元の言語内での単なるプロシジャ呼び出しで済んだ場合の簡便さが頭にあるから、余計大変な気がするのだと思う。

外部プログラムの呼び出しが面倒な理由をつらつら考えてみると、下記が挙げられるように思う。

  • 別のプロセスが起動され、プログラムが並列で実行されてしまう。

シングルスレッドで実行したい場合が多い。何もなければ、シングルスレッドで書きたい。しかし、外部のプログラムを呼び出すと、そこで新しいプロセスが開始されるので、意識して同期を取る必要が出てくる。先に挙げたバッチファイルが並列して実行されてしまったというのは、ここの絡みである。

  • エラー処理が難しい。

外部プログラムの実行結果が容易に分からない。

外部プログラムの終了コードを取れる場合があるが、それ以上の内容となると、外部プログラムが出力する標準出力や標準エラー出力をどこかのファイルに書き出し、そのファイルを読み込むとか、何か方法を考えねばならない。

 

そんな訳で、色々面倒だった記憶があり、自分はつい最近まで、外部プログラムの呼び出しをあまりしたくないと思っていた。しかし、この間、Javaコードで圧縮ファイルの解凍処理を書いたらうまくいかず、止むを得ずJavaから圧縮解凍ソフト「7-zip」を呼び出した所、案外その処理がスムーズにいったので、感動したのである。

Qiitaに記事を書いていて思ったのは、外部プログラムの標準出力、標準エラー出力の出力先をリダイレクトするAPIがあり、ProcessBuilderクラスのredirectOutputメソッド辺りがそうなのだが、これがJava1.7で追加との事で、有難く思った。Javaの標準ライブラリのサポートが、外部プロセスの呼び出しに関して厚くなってきているとしたら、とても嬉しい事である。

  • まとめ

外部プログラムの呼び出しの難しさというのは、結局は平行処理の難しさなのではないか。

異なるプロセス間で適切に連携を取る事の難しさが、外部プログラムの呼び出しにはあると思う。