1

Process Builder を使用して Java でコマンドを実行する際に問題があります。テスト マシンでは正常に動作しますが、サーバー上でコマンドによって開かれたプロセスがフリーズし、終了しません。このコードは、Apache Tomcat Windows Web サーバーで使用されます。

//WORD is the absolute path for msWord and inF is the absolute path
//for the file to save as pdf
public boolean changeFormatMSOffice(String inF, String WORD) {
    System.out.println("changeFormatMSOffice(" + inF + "," + WORD + ")");
    String macro = "";
    ArrayList<String> wordArr = new ArrayList<String>(java.util.Arrays.asList(TO_PDF_WORD.replace(" ", "").split(",")));
    ArrayList<String> excelArr = new ArrayList<String>(java.util.Arrays.asList(TO_PDF_EXCEL.replace(" ", "").split(",")));
    ArrayList<String> ppArr = new ArrayList<String>(java.util.Arrays.asList(TO_PDF_PP.replace(" ", "").split(",")));
    String extension = inF.substring(inF.lastIndexOf(".")).replace(".", "").trim();
    BufferedWriter out;
    List<String> cmdList = new ArrayList<String>();
    cmdList.add(WORD);
    String saveFile = "";
    if (wordArr.contains(extension)) {
        macro = "/msaveAsPDF";
        cmdList.add(macro);
        cmdList.add(inF);
    } else if (excelArr.contains(extension) || ppArr.contains(extension)) {
        if (excelArr.contains(extension)) {
            macro = "/mSaveXLSAsPDF";
        } else {
            macro = "/msavePPTAsPDF";
        }
        cmdList.add(macro);
        int fileNum = 0;
        saveFile = "\"" + PATH + (PATH.substring(PATH.length() - 1).equals(File.separator) ? "" : File.separator) + fileNum + ".txt\"";
        while (new File(saveFile).exists()) {
            fileNum++;
            saveFile = "\"" + PATH + (PATH.substring(PATH.length() - 1).equals(File.separator) ? "" : File.separator) + fileNum + ".txt\"";
        }
        try {
            out = new BufferedWriter(new FileWriter(saveFile));
            out.write(inF);
            out.close();
            cmdList.add(saveFile);
        } catch (Exception e) {
            System.err.println(e.toString());
        }
    }

    try {
        ProcessBuilder proc = new ProcessBuilder(cmdList);
        System.out.println("PreWaitForList");
        Process pro = proc.start(); //<----- important part starts here
        StreamGobbler g1 = new StreamGobbler("stdin", pro.getInputStream());
        StreamGobbler g2 = new StreamGobbler("stderr", pro.getErrorStream());
        g1.start();
        g2.start();
        pro.waitFor();//<---- hangs here, but need to wait for it to exit(system requirement)
        System.out.println("AfterWaitFor");
        try {
            if (!saveFile.equals("")) {
                new File(saveFile).delete();
            }
        } catch (Exception e) {
        }
        return true;
    } catch (Exception e) {
        System.err.println(e.toString());
        return false;
    }
}

std ストリームとエラー ストリームを収集する必要があるという情報が見つかりました。それ以外の場合はフリーズするため、次のストリーム ゴブラーの実装を使用しました。

public class StreamGobbler implements Runnable {

    String name;
    InputStream is;
    Thread thread;

    public StreamGobbler(String name, InputStream is) {
        this.name = name;
        this.is = is;
    }

    public void start() {
        thread = new Thread(this);
        thread.start();
    }

    public void run() {
        try {
            InputStreamReader isr = new InputStreamReader(is);
            BufferedReader br = new BufferedReader(isr);

            while (true) {
                String s = br.readLine();
                if (s == null) {
                    break;
                }
                System.out.println("[" + name + "] " + s);
            }

            is.close();

        } catch (Exception ex) {
            System.out.println("Problem reading stream " + name + "... :" + ex);
            ex.printStackTrace();
        }
    }
}

コマンドラインでコマンドを実行すると、テストマシンとサーバーの両方で機能することに注意してください

4

1 に答える 1

1

Javaとコマンドラインからプロセスを開始するとき、環境パラメーター($ pathなど)と作業ディレクトリは同じですか?

于 2012-04-05T17:47:17.683 に答える