プログラムで処理の途中に既存のバッチを呼び出して、処理を実行させたいこともあるかと思います。
そこで本記事では、Javaプログラムからバッチ処理を実行する方法について、サンプルコードを掲載しながらご紹介していきます。
目次
Java ProcessBuilderについて
Javaには外部プログラムを実行するための機能が集まった「ProcessBuilder」クラスが提供されています。
概要
ProcessBuilderクラスはJava1.5から導入されたクラスで、それまで「Runtime」クラスが担っていた機能をより使いやすく提供しています。
Java1.5以降のRuntimeでは内部処理でProcessBuilderを使っているようなので、特に理由がない限りはProcessBuilderを利用しましょう。
ProcessBuilderクラスを利用することで、「bat」ファイルや「sh」ファイルなど、外部で定義したプログラムをJavaから実行することが出来ます。
使い方
Process Buliderは「インスタンスの生成」「プロセスの開始」「結果の表示」の3ステップで処理を実行していきます。
インスタンスの生成
まずProcess Builderクラスを利用するために、インスタンスの生成処理を記述する必要があります。
ProcessBuilder インスタンス変数 = new ProcessBuilder(); インスタンス変数.command(ファイルパス);
ProcessBuilderクラスをインスタンス化し、commandメソッドにファイルパスを指定します。
また他にもインスタンス化する際、第1引数にコマンド(「sh」や「cmd」など)を入力し、第2引数以降にターミナルで入力するコマンドを記述するような書き方も可能です。
プロセスの開始
作成したインスタンスでプロセスを開始させます。
Process process変数 = インスタンス変数.start();
インスタンス変数で「start()」メソッドを実行し、Processクラスの変数を作成します。
結果の表示
結果の表示には「redirectOutput」と「redirectError」を使って、コンソール出力先をJavaの標準出力に変更しています。
インスタンス変数.redirectOutput(ProcessBuilder.Redirect.INHERIT); インスタンス変数.redirectError(ProcessBuilder.Redirect.INHERIT);
ProcessBuilderでバッチ処理を実行するJavaサンプルコード
ProcessBuilderを使ってJavaプログラムからバッチ処理を実行する具体例を確認していきましょう。
バッチ処理の作成から実際にJavaプログラムから呼び出す方法まで順を追ってご紹介していきます。
呼び出し先のバッチ処理用コマンドを作成する
まずはバッチ処理で実行するコマンドを作成していきます。
Test.sh
サンプルとして、コンソールに文字列を出力するだけのバッチ処理を「Test.sh」として作成します。
#!/bin/bash echo 処理1 echo 処理2 echo 処理3 echo 処理4 echo 処理5
Javaプログラムを作成
次は呼び出し側となるJavaプログラムをProcessBuilderクラスを使って実装していきます。
Main.java
public class Main { public static void main(String[] args) throws Exception { ProcessBuilder pb = new ProcessBuilder(); pb.command("/tmp/Test.sh"); pb.redirectOutput(ProcessBuilder.Redirect.INHERIT); pb.redirectError(ProcessBuilder.Redirect.INHERIT); Process process = pb.start(); int ret = process.waitFor(); System.out.println(ret); } }
実行した結果が下記です。
処理1 処理2 処理3 処理4 処理5 0
外部プログラムに記述した処理を、 Javaプログラムから呼び出せていることが確認出来ます。
出力結果の最後に表示されている「0」は、11行目の処理の出力結果で、処理が正常終了したことを表しています。
JavaプログラムからRuntimeでバッチ処理を実行する方法
JavaプログラムからProcessBuilderでバッチ処理を呼び出す方法をご紹介してきましたが、従来より利用されている「Runtime」を使用した方法についても確認しておきましょう。
シェルスクリプト
シェルスクリプトは「Test.sh」を下記の内容で作成し「/tmp」フォルダに格納しました。
#!/bin/bash echo 処理1 >> "/tmp/test.log" echo 処理2 >> "/tmp/test.log" echo 処理3 >> "/tmp/test.log" echo 処理4 >> "/tmp/test.log" echo 処理5 >> "/tmp/test.log"
Javaプログラム
Javaプログラムは「Main.java」として下記の内容で作成しています。
public class Main { public static void main(String[] args) throws Exception { String bat = "/tmp/Test.sh"; try { Runtime.getRuntime().exec(bat); } catch(Exception e) { System.out.println(e); } } }
6行目に記述している「Runtime.getRuntime().exec()」が外部プログラムを実行するための処理です。
実行した結果をコマンドで確認してみると次のような結果となるはずです。
tmp $ ls Temp.sh -----Javaプログラム実行----- tmp $ ls Temp.sh test.log tmp $ cat test.log 処理1 処理2 処理3 処理4 処理5
このように従来のRuntimeを利用した方法でも、外部プログラムを実行してProcessBuilderクラスと同じ結果を得ることが出来ました。
ただ上述しているように、ProcessBuilderクラスの方がJava1.5より公開された機能改良版となっているため、今後のプログラム作成においては推奨されています。
さいごに: Javaプログラムからバッチ処理を実行してみよう
本記事では、Javaプログラムから外部プログラムを呼び出してバッチ処理を実行する方法についてご紹介してきました。
今回ご紹介したバッチ処理はシンプルなものなので、それほどメリットは感じないかも知れませんが、Javaプログラム実行中に意図的に他のバッチ処理を呼び出せるのは使い方によっては大きなメリットとなり得ます。
バッチ処理としてJavaプログラムを呼び出したことはあっても、今回のようにJavaプログラムからバッチ処理を呼び出す方法は知らない方も多いかと思いますので、ぜひ一度お試しください。
サンプルでは作成したshファイルを「/tmp」に格納しています。