2012-01-23 3 views
0

Итак, у меня есть несколько сценариев оболочки, которые запускаются на сервере. Они проводят некоторое время сбора данных, а затем завершают работу. Кажется, они отлично работают, когда я запускаю их с сервера. Теперь я пытаюсь автоматизировать их с помощью Spring webapp. Все работает, и я могу запускать скрипты через ProcessBuilder, но по какой-то причине, когда скрипты запускаются через ProcessBuilder, они получают только половину, а затем просто перестают отвечать.Webapp, который запускает процесс, не будет завершен

Я действительно надеюсь, что у кого-то появятся мысли о том, почему это может быть. К сожалению, из-за работы я не могу много писать в коде. Я могу опубликовать код 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; 
} 

} 

Я извиняюсь за любые синтаксические ошибки, которые вы видите, код компилируется и работать так, пожалуйста, просто игнорировать их. Я копировал и вставлял соответствующие фрагменты кода и, возможно, что-то испортил в этом отношении.

EDIT

Я добавил некоторые заявления журнала в разных местах и ​​можно увидеть, что код входит мой помощник, поэтому он отображает выход, но в какой-то момент он просто останавливается. он никогда не попадает в сообщения журнала, связанные с методом p.waitFor(). Ясно, что я не делаю что-то правильно, что понятно, потому что потоки - это огромная слабость. Я предполагаю, что, возможно, он повесил трубку, показывая вещи, и я получаю тупиковую ситуацию, но я действительно не понимаю, где и как ее исправить. Может ли кто-нибудь дать мне знать, что я напугаю и что мне нужно сделать, чтобы исправить это? Я мог бы действительно использовать пример, спасибо.

+1

Вы пытались вывести поток stderror и посмотреть, что он говорит? – Max

+1

Похоже, вы забыли сливать выходной поток. – bmargulies

+0

Я не уверен, как вывести поток stderror. Также сказал мне, что я не истощал выходной поток, не очень помогает мне. Если бы вы могли предложить некоторые исправления, я был бы признателен. Threading - это огромная слабость, и даже если мне говорят о проблеме, я все еще не уверен, как ее исправить без некоторых примеров. Благодарю. – cardician

ответ

0

Ну после дальнейшего исследования кажется, что проблема связана с тем, что я неправильно получаю все данные от потоков ввода и ошибок. Думаю, у вас должно быть несколько потоков для каждого потока, чего я до сих пор не понимаю. Я добавил строку, которая вызвала метод redirectErrorStream() объекта processbuilder и, похоже, помогла. Я до сих пор не уверен, что он не будет снова зависеть при обработке больших объемов данных, поскольку я видел кучу разговоров обо всех потоках, которые должны были быть в их собственных потоках, как я уже упоминал, но я не совсем уверен, как Я должен это сделать. Очень сложно найти хороший краткий пример использования ProcessBuilder. Однако это, похоже, устранило проблему, с которой я столкнулся.

+0

это каноническая статья для правильного использования Java-процессов: http: // www .javaworld.com/javaworld/jw-12-2000/jw-1229-traps.html – jtahlborn

+0

@ cardician: Это не о том, чтобы критиковать вас, это просто необычное использование сущности и ее возможных побочных эффектов! – home

0

Я не могу много помочь, не говоря уже о том, почему ваш процесс висит. Однако ваша организация не должна быть работоспособной. Извлеките это в службу, вы можете сохранить свой идентификатор процесса в своей сущности, если вам нужно сопоставить его с процессом.

+0

Я не знаю, почему это висит. Это именно то, что я пытаюсь спросить. И, как я уже сказал, я действительно не очень хорош в потоках или чем-то связанном, поэтому я просто помещаю этот код вместе, поскольку я так или иначе могу заставить его работать.Я ценю, что вы предоставили немного больше информации об альтернативе тому, чтобы моя сущность была работоспособной. Я могу попробовать изменить это, как только я получу код для работы. – cardician

+0

@ cardician: Дайте ему попробовать без какого-либо контекста - удалите все зависимости Spring + JPA и вызовите внешний процесс из отдельной программы (JUnit и т. Д.) – home

Смежные вопросы