Interstage Web Server 使用上の注意 - Solaris -
目次 前ページ次ページ

第3章 注意事項> 3.10 JDK/JREの注意事項

3.10.7 java.lang.Runtime.exec()使用時の注意事項

java.lang.Runtimeクラスのexexメソッドで、別プログラムを実行する際の注意事項を、以下で説明します。

■仮想メモリ不足による例外発生

仮想メモリが不足している状態でRuntimeクラスのexecメソッドで子プロセスを実行するとjava.io.IOExceptionが発生する場合があります。
この場合は、次のどれかの方法で対処してください。

■ファイルディスクリプタ不足による例外発生

オープンされたファイルが多い状態でRuntimeクラスのexecメソッドで子プロセスを実行すると、ファイルディスクリプタ(fd)が不足し、java.io.IOExceptionなどの例外が発生する場合があります。
この場合は、子プロセスに対する入出力ストリームを明示的にクローズするようにプログラムを見直してください。
次の例を参考にしてください。

子プロセスに対する入出力ストリームのクローズ処理

Process p = Runtime.getRuntime().exec(...);
    :
p.waitFor();                 // 子プロセスの終了を待つ
p.getInputStream().close();  // 標準出力ストリームをクローズ
p.getErrorStream().close();  // 標準エラー出力ストリームをクローズ
p.getOutputStream().close(); // 標準入力ストリームをクローズ

■子プロセスのストリームに対する入出力

親プロセスがRuntime.execメソッドで子プロセスを実行する際、子プロセスの標準入力、標準出力、標準エラー出力のそれぞれに対してパイプを作成します。
このため、子プロセスが、標準入力からの入力を待っている状態になったり、標準出力および標準エラー出力へ出力できない状態になったりした場合、子プロセス自身の処理が進まず、子プロセスがブロックされるか、デッドロックになる場合があります。

したがって、子プロセスの標準入力への書込みおよび、標準出力、標準エラー出力からの読込みを行う処理を確実に迅速に行うようにしてください。

次の例を参考にして、プログラミングしてください。

子プロセスの標準出力、標準エラー出力に対する入力処理の例

import java.io.*;

public class ProcessSample {
    public static void main(String[] args) {
        new ProcessSample();
    }

    public ProcessSample() throws Exception {
        // "sort data.txt"を、子プロセスとして実行
        // sortは、テキストをソートするコマンド
        // data.txtは、javaプロセスのカレントディレクトリ上のテキストファイル
        Process p = Runtime.getRuntime().exec("sort data.txt");

        // 子プロセスの標準出力および標準エラー出力を入力するスレッドを起動
        new StreamThread(p.getInputStream(), "stdout.txt").start();
        new StreamThread(p.getErrorStream(), "stderr.txt").start();

        // 子プロセスの終了を待つ
        p.waitFor();
    }

    /**
     *子プロセスの出力ストリームから入力し、ファイルに出力するスレッド
     */
    class StreamThread extends Thread {
        private static final int BUF_SIZE = 4096;
        private InputStream in;
        private BufferedOutputStream out;

        public StreamThread(InputStream in, String outputFilename) throws IOException {
            this.in  = in;
            this.out = new BufferedOutputStream(new FileOutputStream(outputFilename));
        }

        public void run(){
            byte[] buf = new byte[BUF_SIZE];
            int size = -1;
            try{
                while((size = in.read(buf, 0, BUF_SIZE)) != -1){
                    out.write(buf, 0, size);
                }
            }catch(IOException ex){
                ex.printStackTrace();
            }finally{
                try{in.close();} catch(IOException ex){}
                try{out.close();}catch(IOException ex){}
            }
        }
    }
}

目次 前ページ次ページ

Copyright 2008 FUJITSU LIMITED