0

I tried implementing spring batch retry as mentioned in this problem and i was successful in implementing it. I wanted to implement the same with calling jobLauncher.run outside the doWithRetry function. This is so that anytime I can use the RetryTemplate without containing the JobExecution. If that is possible, how can I achieve that? Currently my source code looks like this-

        @Configuration
        @EnableBatchProcessing
        public class RetryBatchJob {

          @Autowired
          private JobBuilderFactory jobs;

          @Autowired
          private StepBuilderFactory steps;

          @Bean
          public ItemReader<Integer> itemReader() {
            return new ListItemReader<>(Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10));
          }

          @Bean
          public ItemWriter<Integer> itemWriter() {
            return items -> {
              for (Integer item : items) {
                System.out.println("item = " + item);
                if (item.equals(7)) {
                  throw new Exception("Sevens are sometime nasty, let's retry them");
                }
              }
            };
          }

          @Bean
          public Step step() {
            return steps.get("step")
              .<Integer, Integer>chunk(2)
              .reader(itemReader())
              .writer(itemWriter())
              .build();
          }

          @Bean
          public RetryTemplate retryTemplate() {
            RetryTemplate retryTemplate = new RetryTemplate();

            SimpleRetryPolicy retryPolicy = new SimpleRetryPolicy(5, singletonMap(Exception.class, true));
            retryPolicy.setMaxAttempts(5);
            retryTemplate.setRetryPolicy(retryPolicy);

            return retryTemplate;
          }

        public static void main(String[] args) throws Exception {
        ApplicationContext context = new AnnotationConfigApplicationContext(RetryBatchJob.class);
        JobLauncher jobLauncher = context.getBean(JobLauncher.class);
        Job job = context.getBean(Job.class);

        RetryTemplate retryTemplate = context.getBean(RetryTemplate.class);
        retryTemplate.execute(new RetryCallback<JobExecution, Exception>() {
            @Override
            public JobExecution doWithRetry(RetryContext context) throws Exception {
            JobExecution exe = jobLauncher.run(job, new JobParameters());       
            if(exe.getStatus().equals(BatchStatus.FAILED))
               throw new RuntimeException(exe.toString());
            return exe; 
            };
        });
       }

    }
          

  • What do you mean by "This is so that anytime I can use the RetryTemplate without containing the JobExecution"? Can you explain what are you trying to achieve? – Mahmoud Ben Hassine Jun 25 '20 at 09:43
  • If any other complex batch i have, it might be problematic (not any ex. as of now just a thought) to have jobExecution inside the doWithRetry function. Also, I wanted to explore if I could use it relating with `afterJob` method because there also we can check, `BatchStatus.FAILED` condition, so this was a thought to somewhat standardise the process of Retry in Spring Batch. – Apoorv Bansal Jun 25 '20 at 16:53
  • Can you explain what are you trying to achieve? – Mahmoud Ben Hassine Jun 25 '20 at 18:04
  • I wanted to know that if we can use the `afterJob` listener and checking`BATCH.FAILED` condition in the listener and then retrying the failed job? If so, then how. – Apoorv Bansal Jun 27 '20 at 18:32
  • No, because `afterJob` is part of the current job execution. A job cannot (and should not) restart itself. You run the job, get its job execution, and then decide to re-run or not , either manually (by using a second call to JobLauncher#run or JobOperator#restart) or automatically (using a retry template). – Mahmoud Ben Hassine Jun 27 '20 at 20:44

0 Answers0