我正在制作一个具有批处理和处理器的Spring Batch应用程序。 在处理器中,我引发了异常,而我的需要是根据我引发的异常将System.exit()应用程序。
但是我不知道该怎么做。
感谢您的答复
答案 0 :(得分:0)
您可以在此article中找到很好的解释。一种实现方法是提供ExitCodeExceptionMapper
bean,以将异常映射到某些特定的退出代码:
@Bean
ExitCodeExceptionMapper exceptionMapper() {
return exception -> {
if (exception.getCause() instanceof NumberFormatException) {
return 80;
}
return 1;
};
}
更新
这个小例子应该很清楚:
@SpringBootApplication
public class DemoApplication implements CommandLineRunner {
@Bean
ExitCodeExceptionMapper exitCodeExceptionMapper() {
return exception -> {
if (exception.getCause() instanceof MyException) {
return 10;
}
return 1;
};
}
public static void main(String[] args) {
System.exit(SpringApplication
.exit(SpringApplication.run(DemoApplication.class, args)));
}
@Override
public void run(String... args) throws Exception {
throw new MyException();
}
private class MyException extends RuntimeException {}
}
然后我执行以下命令来运行该应用程序:
mvn package
java -jar target/demo-1.0.0-SNAPSHOT.jar
执行此命令后,我可以使用以下Windows命令检查退出代码:
echo Exit Code is %errorlevel%
它返回:
Exit Code is 10
答案 1 :(得分:0)
我需要根据我抛出的异常对System.exit()应用程序
我不建议调用System.exit
来杀死您的应用程序,因为这会导致您在不正常关闭进程和清理资源的情况下终止您的工作。
如果使用CommandLineJobRunner
,则可以提供自定义ExitCodeMapper
。看到这里:https://docs.spring.io/spring-batch/4.0.x/reference/html/job.html#exitCodes
如果使用Spring Boot,则需要使用返回值System.exit
来调用SpringApplication
。您可以在这里找到一个示例:https://github.com/spring-projects/spring-boot/blob/master/spring-boot-samples/spring-boot-sample-batch/src/main/java/sample/batch/SampleBatchApplication.java#L67,并在以下参考文档中找到更多详细信息:https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-application-exit
现在要能够自定义处理器中发生异常时作业的退出代码,您需要:
ExitCodeGenerator
通过Spring Boot发送的JobExectutionEvent
来访问作业执行并自定义退出代码这里是一个例子:
@Configuration
@EnableBatchProcessing
public class MyJob {
@Autowired
private JobBuilderFactory jobs;
@Autowired
private StepBuilderFactory steps;
@Bean
public Step step() {
return steps.get("step")
.<Integer, Integer>chunk(2)
.reader(new ListItemReader<>(Arrays.asList(1, 2, 3, 4)))
.processor(new ItemProcessor<Integer, Integer>() {
private StepExecution stepExecution;
@BeforeStep
public void beforeStep(StepExecution stepExecution) {
this.stepExecution = stepExecution;
}
@Override
public Integer process(Integer item) {
if (item.equals(3)) {
stepExecution.getJobExecution().getExecutionContext().put("failure", "item not accepted");
throw new IllegalArgumentException("3 is not accepted");
}
return item;
}
})
.writer(items -> {
for (Integer item : items) {
System.out.println("item = " + item);
}
})
.build();
}
@Bean
public Job job() {
return jobs.get("job")
.start(step())
.listener(new JobExecutionListenerSupport() {
@Override
public void afterJob(JobExecution jobExecution) {
String failure = jobExecution.getExecutionContext().getString("failure");
if (failure != null && failure.equalsIgnoreCase("item not accepted")) {
jobExecution.setExitStatus(new ExitStatus("Not Accepted"));
}
}
})
.build();
}
@Bean
public ExitCodeGenerator exitCodeGenerator () {
return new MyExitCodeGenerator();
}
static class MyExitCodeGenerator implements ExitCodeGenerator, ApplicationListener<JobExecutionEvent> {
private JobExecution jobExecution;
@Override
public int getExitCode() {
if (jobExecution.getExitStatus().getExitCode().equalsIgnoreCase("Not Accepted")) {
return 42;
}
return 0;
}
@Override
public void onApplicationEvent(JobExecutionEvent jobExecutionEvent) {
this.jobExecution = jobExecutionEvent.getJobExecution();
}
}
}
如果您使用以下命令运行此
:@SpringBootApplication
public class DemoExitCodeApplication {
public static void main(String[] args) {
System.exit(
SpringApplication.exit(
SpringApplication.run(DemoExitCodeApplication.class, args)
)
);
}
}
JVM的退出代码是42,这是在处理器中引发异常时设置的值。