简体   繁体   English

Java-如何在SpringBatch应用程序中设置ExitCode

[英]Java - How to set ExitCode in SpringBatch Application

I am making a Spring Batch application where I have tasklet and processor. 我正在制作一个具有Tasklet和处理器的Spring Batch应用程序。 In the processor I throw Exceptions, and my needs is to System.exit() the application according to the exceptions I thrown. 在处理器中,我引发了异常,而我的需要是根据我引发的异常将System.exit()应用程序。

But I don't know how to do this. 但是我不知道该怎么做。

Thanks for your reply 感谢您的回复

You can find a good explanation in this article . 您可以在本文中找到很好的解释。 One way to do it is to provide the ExitCodeExceptionMapper bean to map the exception to some specific exit code: 一种方法是提供ExitCodeExceptionMapper bean,以将异常映射到某些特定的退出代码:

@Bean
ExitCodeExceptionMapper exceptionMapper() {
    return exception -> {
        if (exception.getCause() instanceof NumberFormatException) {
            return 80;
        }
        return 1;
    };
}

UPDATE 更新

This small example should make it clear: 这个小例子应该很清楚:

@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 {}
}

Then I execute the following commands to run the app: 然后,我执行以下命令来运行该应用程序:

mvn package
java -jar target/demo-1.0.0-SNAPSHOT.jar

After this commands I can check the exit code with the following command for windows: 执行此命令后,我可以使用以下Windows命令检查退出代码:

echo Exit Code is %errorlevel%

And it returns: 它返回:

Exit Code is 10

my needs is to System.exit() the application according to the exceptions I thrown 我需要根据抛出的异常对System.exit()应用程序

I would not recommend to call System.exit to kill your application as this will kill your job without gracefully shutting down the process and cleaning up resources. 我不建议调用System.exit杀死您的应用程序,因为这将杀死您的工作,而不会正常关闭进程并清理资源。

If you use the CommandLineJobRunner , you can provide a custom ExitCodeMapper . 如果使用CommandLineJobRunner ,则可以提供自定义ExitCodeMapper See here: https://docs.spring.io/spring-batch/4.0.x/reference/html/job.html#exitCodes 看到这里: https : //docs.spring.io/spring-batch/4.0.x/reference/html/job.html#exitCodes

If you use Spring Boot, you need to call System.exit with the return value of SpringApplication . 如果使用Spring Boot,则需要使用SpringApplication的返回值调用System.exit You can find an example here: https://github.com/spring-projects/spring-boot/blob/master/spring-boot-samples/spring-boot-sample-batch/src/main/java/sample/batch/SampleBatchApplication.java#L67 and more details in the reference documentation here: https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-application-exit 您可以在此处找到示例: 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

Now to be able to customise the exit code of the job when an exception occurs in the processor, you need to: 现在,要能够在处理器中发生异常时自定义作业的退出代码,您需要:

  • propagate this information at the job level. 在作业级别传播此信息。 This is possible by getting access to the job execution context in your processor and then use it in a job listener 这可以通过访问处理器中的作业执行上下文,然后在作业侦听器中使用它来实现。
  • use a custom ExitCodeGenerator to get access to the job execution through the JobExectutionEvent sent by Spring Boot and customise the exit code 使用自定义的ExitCodeGenerator通过Spring Boot发送的JobExectutionEvent获取对作业执行的访问权限,并自定义退出代码

Here is an example: 这是一个例子:

@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();
    }
   }

}

If you run this with: 如果使用以下命令运行此命令:

@SpringBootApplication
public class DemoExitCodeApplication {

public static void main(String[] args) {
    System.exit(
            SpringApplication.exit(
                SpringApplication.run(DemoExitCodeApplication.class, args)
            )
    );
   }
}

The exit code of the JVM is 42, which is what was set when an exception is thrown in the processor. JVM的退出代码为42,这是在处理器中引发异常时设置的代码。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM