2016-02-24 191 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(); 

希望这个答案可以帮助别人......