Java 进程永远不会以processBuilder结束
使用Process builder在java中运行命令时遇到问题。在测试机器中,它工作正常,但一旦在服务器上,由命令打开的进程就会冻结,并且永远不会退出。此代码用于apache tomcat windows web服务器:Java 进程永远不会以processBuilder结束,java,Java,使用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(Stri
//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;
}
}
请注意,在命令行中运行命令时,在测试机和服务器中,当您从java启动进程时,环境参数(如$path)和工作目录与命令行相同吗?是环境参数(如$path)从java启动进程时,工作目录与从命令行启动进程时相同?您可以尝试关闭进程。getOutputStream()您可以尝试关闭进程。getOutputStream()是的,我有一个“System.out.printLn”(“\”+cmdList[0]+“\”+cmdList[1]+“\”+cmdList[2]+“\”;”要打印它,只需将复制粘贴到CMD,这些只是命令参数,而不是环境变量。命令行参数是绝对路径,除非我不理解环境变量的用法,否则我没有使用它们,在我的代码中,路径也是一个常量,用于引用文件的保存位置,我有一个“System.out.printLn”(“\”“+cmdList[0]+”\”“+cmdList[1]+“\”“+cmdList[2]+”);”要打印它,只需将复制粘贴到CMD,这些只是命令参数,而不是它的环境变量。命令行参数是绝对路径,除非我不理解环境变量的用法,否则我没有使用它们,在我的代码中,路径也是一个常量,用于引用文件保存的位置
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();
}
}
}