process never ends with processBuilder

Go To StackoverFlow.com

1

I have a problem running a command in java using the Process builder. In the test machine it works correctly but once on the server the proccess being opened by the command freezes and never exits. this code is used on an apache tomcat windows web server:

//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;
    }
}

i found information saying that you need to collect the std and error streams else it will freze so i used the following stream gobbler implementation:

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();
        }
    }
}

note that while running the command in the command line it works, in both the test machine and in the server

2012-04-05 15:19
by Ricardo Garza V.
You could try closing process.getOutputStream( - benmmurphy 2012-04-05 15:47


1

Are the environment parameters (like $path) and the working directory the same when you start the process from java vs the command line?

2012-04-05 17:47
by daveb
yes, i had a 'System.out.printLn("\""+cmdList[0]+"\" " + cmdList[1] +" \""+cmdList[2]+"\"");' to print it, and just make copy paste to the cm - Ricardo Garza V. 2012-04-05 18:11
Those are just the command arguments, not it's environment variable - daveb 2012-04-05 18:34
the command line arguments are absolute paths, unless I missunderstand the use of the enviroment variables I am not making use of them, also the PATH, in my code is a constant to reference the place where the files are save - Ricardo Garza V. 2012-04-05 18:52
Ads