2012-01-23 5 views
0

그래서 서버에서 실행되는 몇 가지 쉘 스크립트가 있습니다. 그들은 시간 집약적 인 데이터 수집을 수행 한 다음 완료합니다. 그들은 서버에서 실행할 때 잘 작동하는 것 같습니다. 이제는 스프링 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; 
} 

} 

구문 오류가 있으면 사과드립니다. 코드는 컴파일되고 실행되므로 무시하십시오. 나는 관련 코드 비트를 복사하여 붙여 넣고 있었고 그 점에 관해 뭔가를 엉망으로 만들었을 것이다.

편집

나는 다른 장소에서 일부 로그 문을 추가 코드가 출력을 표시하는 이유입니다 내 도우미를 입력하는 것을 볼 수 있지만, 어떤 점에서 그냥 중지합니다. 그것은 p.waitFor() 메소드를 둘러싸고있는 로그 문을 치는 것처럼 보이지 않습니다. 분명히 나는 ​​옳은 일을하고 있지 않다. 왜냐하면 스레드는 내 약점이기 때문에 이해할 수있다. 어쩌면 그것은 물건을 표시하는 걸 멈추고 교착 상태에 빠졌을 것 같지만 실제로 수정해야 할 위치 나 방법을 이해하지 못합니다. 누구든지 내가 망쳐 놓고 무엇을 고칠 필요가 있는지 알려 줄 수 있습니까? 정말 예제도 사용할 수 있습니다. 감사합니다.

+1

stderror 스트림을 출력하고 그 내용을 보았습니까? – Max

+1

출력 스트림을 배출하는 것을 잊어 버린 것 같습니다. – bmargulies

+0

stderror 스트림을 출력하는 방법을 모르겠습니다. 또한 출력 스트림을 배수시키지 않았다고해서 나에게 많은 도움이되지는 않는다. 만약 당신이 제게 그것을 고맙게 생각할 수있는 수정 프로그램을 제공 할 수 있습니다. 스레딩은 제게 큰 약점입니다. 문제를 말하면서도 몇 가지 예제없이 문제를 해결하는 방법을 아직 잘 모릅니다. 감사. – cardician

답변

0

더 많은 연구가 끝난 후에도 입력 및 오류 스트림에서 모든 데이터를 제대로 가져 오지 못하는 것과 관련된 문제인 것 같습니다. 나는 각 스트림에 대해 여러 개의 스레드가 있어야한다고 생각하는데, 아직도 이해할 수 없습니다. 나는 processbuilder 객체에 redirectErrorStream() 메소드를 호출 한 라인을 추가했는데 이것이 도움이 된 것 같습니다. 앞서 언급했듯이 모든 스트림이 자신의 스레드에 있어야한다는 이야기를 여러 번 본 것처럼 많은 양의 데이터를 처리 할 때 다시 응답하지 않을 것이라는 확신이 들지 않습니다. 나는 그렇게해야만 해. ProcessBuilder 사용법에 대한 간결한 예제를 찾는 것은 매우 어렵습니다. 그러나 이것은 내가 가지고있는 문제를 해결 한 것으로 보인다.

+0

이것은 java 프로세스를 올바르게 사용하기위한 표준 기사입니다. http : // www .javaworld.com/javaworld/jw-12-2000/jw-1229-traps.html – jtahlborn

+0

@cardician : 그것은 당신을 비판하는 것이 아니라, Entity의 비정상적인 사용과 가능한 부작용에 관한 것입니다! – home

0

귀하의 프로세스가 걸려있는 이유에 대해 더 많은 내용없이 도움을 줄 수는 없습니다. 그러나 엔티티는 실행 가능해서는 안됩니다. 이것을 서비스에 추출하면 프로세스 ID를 엔티티에 저장할 수 있습니다.

+0

왜 걸려 있는지 알 수 없습니다. 그게 정확히 내가 물어 보려는 것입니다. 그리고 내가 말했듯이 스레드 나 다른 것들과 관련해서는별로 좋지 않습니다. 그래서 어떤 식 으로든이 코드를 작동 시키면됩니다.내 엔티티를 실행할 수있게하는 대안에 대한 정보를 조금 더 제공해 주셔서 감사합니다. 실제로 작동하도록 코드를 얻으면 변경할 수 있습니다. – cardician

+0

@cardician : 모든 컨텍스트없이 시도하십시오 - 모든 Spring + JPA 종속성을 제거하고 별도의 프로그램 (JUnit 등) 내에서 외부 프로세스를 호출하십시오 – home

관련 문제