2016-02-24 146 views
0

我找不到在異步上下文中處理spring-batch異常的正確方法。異步TaskManager處理作業/步異常

當我將ThreadPoolTask​​Manager設置到我的JobLauncher時,真正的作業/步驟異常不再被記錄下來。相反,日誌將是這樣的:

org.springframework.batch.core.JobInterruptedException: Job interrupted by step execution 
at org.springframework.batch.core.job.SimpleStepHandler.handleStep(SimpleStepHandler.java:165) 
at ... 

我試圖解決這個添加JobExecutionListener這樣的:

@Override 
public void afterJob(JobExecution jobExecution) { 
    List<Throwable> jobExceptions = jobExecution.getFailureExceptions(); 
    if (CollectionUtils.isNotEmpty(jobExceptions)) { 
     Throwable lastJobException = jobExceptions.get(jobExceptions.size() - 1); 
     LOGGER.error("Spring-Batch error at job level", lastJobException); 
     String lastJobExceptionMessage = ExceptionUtils.getRootCauseMessage(lastJobException); 

     // storing message in ExecutionContext for the batch-admin webapp 
     String message = ""; 
     if (jobExecution.getExecutionContext().get(Consts.JOB_EXECUTION_MESSAGE_KEY) != null) { 
      message = jobExecution.getExecutionContext().getString(Consts.JOB_EXECUTION_MESSAGE_KEY); 
     } 
     message += "\n" + lastJobExceptionMessage; 
     jobExecution.getExecutionContext().put(Consts.JOB_EXECUTION_MESSAGE_KEY, message); 
    } 

} 

但我仍然有JobInterruptedException結束。 有沒有一種方法來檢索中斷的最初原因(可能是在閱讀器/處理器/寫器的代碼錯誤?

感謝,

西里爾

回答

1

我不認爲你的診斷是。正確的,例外只有在SimpleStepHandler拋出與錯誤信息:

if (currentStepExecution.getStatus() == BatchStatus.STOPPING 
     || currentStepExecution.getStatus() == BatchStatus.STOPPED) { 
    // Ensure that the job gets the message that it is stopping 
    execution.setStatus(BatchStatus.STOPPING); 
    throw new JobInterruptedException("Job interrupted by step execution"); 
} 

且僅當該步驟本身沒有拋出JobInterruptedException哪裏會發生這種情況最明顯的例子是,如果該工作已停止。見this example,其輸出與

 
INFO: Executing step: [step1] 
Feb 24, 2016 1:25:02 PM org.springframework.batch.core.repository.support.SimpleJobRepository checkForInterruption 
INFO: Parent JobExecution is stopped, so passing message on to StepExecution 
Feb 24, 2016 1:25:02 PM org.springframework.batch.core.step.ThreadStepInterruptionPolicy isInterrupted 
INFO: Step interrupted through StepExecution 
Feb 24, 2016 1:25:02 PM org.springframework.batch.core.step.AbstractStep execute 
INFO: Encountered interruption executing step step1 in job myJob : Job interrupted status detected. 
Feb 24, 2016 1:25:02 PM org.springframework.batch.core.repository.support.SimpleJobRepository checkForInterruption 
INFO: Parent JobExecution is stopped, so passing message on to StepExecution 
Feb 24, 2016 1:25:02 PM org.springframework.batch.core.job.AbstractJob execute 
INFO: Encountered interruption executing job: Job interrupted by step execution 
Feb 24, 2016 1:25:02 PM org.springframework.batch.core.launch.support.SimpleJobLauncher$1 run 
INFO: Job: [SimpleJob: [name=myJob]] completed with the following parameters: [{}] and the following status: [STOPPED] 
Status is: STOPPED 

This other example結束表明,扔使用線程池時異常改變不了什麼。最終輸出是

 
INFO: Executing step: [step1] 
Feb 24, 2016 1:28:44 PM org.springframework.batch.core.step.AbstractStep execute 
SEVERE: Encountered an error executing step step1 in job myJob 
java.lang.RuntimeException: My exception 
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) 
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57) 
(...) 

Feb 24, 2016 1:28:44 PM org.springframework.batch.core.launch.support.SimpleJobLauncher$1 run 
INFO: Job: [SimpleJob: [name=myJob]] completed with the following parameters: [{}] and the following status: [FAILED] 
Status is: FAILED, job execution id 0 
    #1 step1 FAILED 
Step step1 
java.lang.RuntimeException: My exception 
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) 
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57) 
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) 
(...) 
+0

好,謝謝,所以讓我重新說說我的問題:可能是我的工作/步驟在異步情況下獲得STOPPED的原因是什麼?以及如何查找並記錄該原因 –

+0

@CyrilDejonghe我不知道。嘗試在'StepExecution :: setStatus'中放置一個斷點,並觀察值爲'STOPPED'或'STOPPING'的時間。 – Artefacto

+0

我試圖調試更多細節,但我被困在Spring-Batch的最深處。例如,我在[RepeatTempalte#doHandle()](https://jira.spring.io/browse/BATCH-2479)中遇到了NullPointerException ...我可能會問一個關於配置Async JobLauncher的更通用的問題,但是文檔似乎很清楚...... –

0

所以答案是如此簡單,不是真的覺得很愚蠢時,我的理解是: @Artefacto是正確的。工作停止了。過程結束。因爲它已到達main()方法的末尾。

當我切換到我的ThreadPoolTask​​Manager異步模式,我忘了一個非常重要的行添加到我的主要方法:

// Wait for the end of the JobExecution 
    main.endOfJobLatch.await(); 

希望這個答案可以幫助別人......