运行过程的Webapp无法完成

时间:2012-01-23 18:05:35

标签: java multithreading spring shell

所以我有一些在服务器上运行的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()方法的日志语句。显然我没有做正确的事情,这是可以理解的,因为线程是我的一个巨大的弱点。我猜也许它正在挂起显示的东西,然后我遇到了僵局,但我真的不明白在哪里或如何解决它。任何人都可以让我知道我搞砸了什么以及我需要做些什么来解决它?我也可以使用一个例子,谢谢。

2 个答案:

答案 0 :(得分:0)

如果没有关于您的流程为何悬而未决的更多背景信息,我无能为力。但是,您的实体不应该是可运行的。将其解压缩为服务,如果需要将流程ID映射回流程,则可以将流程ID存储在实体中。

答案 1 :(得分:0)

经过更多的研究后,似乎问题与我无法正确获取输入和错误流中的所有数据有关。我猜你应该为每个流都有多个线程,我仍然不明白。我在processbuilder对象上添加了一个调用redirectErrorStream()方法的行,这似乎有所帮助。我仍然不确定在处理大量数据时它不会再次挂起,因为我已经看到一些关于所有流需要在我们自己的线程中的讨论,但我不确定如何我应该这样做。很难找到一个如何使用ProcessBuilder的简洁示例。但是,这似乎解决了我遇到的问题。