所以我有一些在服务器上运行的shell脚本。他们做了一些时间密集的数据收集,然后完成。当我从服务器运行它们时,它们似乎工作正常。我现在正尝试使用Spring webapp自动执行这些操作。一切都在运行,我可以通过ProcessBuilder运行脚本,但出于某种原因,当脚本通过ProcessBuilder运行时,它们只会到达中途,然后才会停止响应。
我真的希望有人会对这可能是什么有所了解。不幸的是,由于这项工作,我无法真正发布代码方式。我可以发布运行流程的webapp代码,我将在下面做,但我不能发布脚本。如果有人有一些想法,请加入。谢谢。
@Entity
public class Job implements Runnable {
@Id @GeneratedValue
private Long id;
//getters and setters
@Override
public void run() {
Process p = null;
try {
BufferedWriter bw = new BufferedWriter(new FileWriter("/opt/condor/bin/datafile"));
bw.write(this.getName());
bw.close();
p = new ProcessBuilder("/opt/condor/bin/scripts/create-filter.sh").start();
jobHelper(p);
List<String> dates = datesBetween();
status = "Running Master";
for(String temp : dates) {
String[] splitDate = temp.split("-");
String tmpYear = splitDate[0];
String tmpMonth = splitDate[1];
String tmpDay = splitDate[2];
log.info("Running Master script: master.sh " + this.getCustomer() + ", " + this.getProject() + ", " + tmpYear + ", " + tmpMonth + ", " + tmpDay);
p = new ProcessBuilder("/opt/condor/bin/scripts/master.sh", this.getCustomer(), this.getProject(), tmpYear, tmpMonth, tmpDay).start();
log.info("Entering job helper");
jobHelper(p);
log.info("exited job helper");
}
status = "Finished Master";
log.info("Finished Master");
} catch (IOException ioe) {
log.error("IO Error: " , ioe);
ioe.printStackTrace();
}
log.info("Done running script");
endTime = Long.toString(System.currentTimeMillis());
status = "Ended";
JobManager.FinishJob(this);
}
private boolean jobHelper(Process p) {
log.info("inside job helper");
BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line;
try {
while ((line = br.readLine()) != null) {
log.info(line);
if(line.contains("Uh oh!"))
return true;
}
boolean running = true;
while(running) {
log.info("waiting...");
p.waitFor();
log.info("done waiting");
running = false;
}
} catch (IOException e) {
log.error("IO Error: " , e);
e.printStackTrace();
} catch (InterruptedException e) {
log.error("Interrupted Exception: ", e);
e.printStackTrace();
p.destroy();
}
return false;
}
}
我为你看到的任何语法错误道歉,代码编译并运行,所以请忽略它们。我正在复制并粘贴相关的代码,可能在这方面搞砸了。
修改
我在不同的地方添加了一些日志语句,可以看到代码正在进入我的帮助器,这就是它显示输出的原因,但在某些时候它只是停止了。它似乎永远不会碰到围绕p.waitFor()方法的日志语句。显然我没有做正确的事情,这是可以理解的,因为线程是我的一个巨大的弱点。我猜也许它正在挂起显示的东西,然后我遇到了僵局,但我真的不明白在哪里或如何解决它。任何人都可以让我知道我搞砸了什么以及我需要做些什么来解决它?我也可以使用一个例子,谢谢。
答案 0 :(得分:0)
如果没有关于您的流程为何悬而未决的更多背景信息,我无能为力。但是,您的实体不应该是可运行的。将其解压缩为服务,如果需要将流程ID映射回流程,则可以将流程ID存储在实体中。
答案 1 :(得分:0)
经过更多的研究后,似乎问题与我无法正确获取输入和错误流中的所有数据有关。我猜你应该为每个流都有多个线程,我仍然不明白。我在processbuilder对象上添加了一个调用redirectErrorStream()
方法的行,这似乎有所帮助。我仍然不确定在处理大量数据时它不会再次挂起,因为我已经看到一些关于所有流需要在我们自己的线程中的讨论,但我不确定如何我应该这样做。很难找到一个如何使用ProcessBuilder的简洁示例。但是,这似乎解决了我遇到的问题。