Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

@BeforeStep annotated method not being called

Tags:

spring-batch

I am writing a spring batch job. But when this Archive class which implenets the tasklet interface in loaded, the method under the annotation @BeforeStep is not being called. Can anyone help me with this ? Thank You

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
import java.util.Calendar;
import java.util.Locale;
import java.util.TimeZone;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

import org.springframework.batch.core.JobExecution;
import org.springframework.batch.core.StepContribution;
import org.springframework.batch.core.StepExecution;
import org.springframework.batch.core.annotation.BeforeStep;
import org.springframework.batch.core.scope.context.ChunkContext;
import org.springframework.batch.core.step.tasklet.Tasklet;
import org.springframework.batch.item.ExecutionContext;
import org.springframework.batch.repeat.RepeatStatus;


    public class Archive implements Tasklet{
        @Override
        public RepeatStatus execute(StepContribution arg0, ChunkContext arg1)
                throws Exception {

            System.out.println("in execute method :)");
            return RepeatStatus.FINISHED;
        }

        @BeforeStep
        public void retrieveInterstepData(StepExecution stepExecution){
            JobExecution jobExecution = stepExecution.getJobExecution();
            ExecutionContext jobContext = jobExecution.getExecutionContext();

        }
    }
like image 553
Dheeraj Avatar asked Apr 29 '15 06:04

Dheeraj


2 Answers

An third solution to do it: you probably not registered your tasklet as a listener so the annotated method is not called from the start. You can provide the tasklet reference as a listener in your job xml definition like this:

<job id="yourJob" > 
    <step id="step1">
            <tasklet ref="archive">
                <listeners>
                    <listener ref="archive" />
                </listeners>
            </
        </step>
</job> 

you also have to annotate you Archive class with:

@Component("archive")
@Scope("step")
like image 85
guilhermerama Avatar answered Dec 30 '22 16:12

guilhermerama


First solution can be to extract ExecutionContext from execute method where you have ChunkContext and do with it whatever you need.

ExecutionContext jobContext = chunkContext.getStepContext()
                                    .getStepExecution()
                                    .getJobExecution()
                                    .getExecutionContext();

Second solution can be to implement StepExecutionListener and override beforeStep method. You will have something like:

public class Archive implements Tasklet, StepExecutionListener{
    @Override
    public RepeatStatus execute(StepContribution arg0, ChunkContext arg1)
                throws Exception {
        System.out.println("in execute method :)");
        return RepeatStatus.FINISHED;
    }

    @Override
    public void beforeStep(final StepExecution stepExecution) {
        JobExecution jobExecution = stepExecution.getJobExecution();
        ExecutionContext jobContext = jobExecution.getExecutionContext();
    }
}

I had a similar problem and we overcomed it like this. As for why @BeforeStep is not called on tasklet but it is inside readers, processors and writers I am not sure.

like image 39
Nenad Bozic Avatar answered Dec 30 '22 15:12

Nenad Bozic