0

New to spring batch and trying to achieve Partition for a big input of data. I already checked the below solution which are similar to my problem but can't resolve the issue.

Spring Batch : Field or property 'stepExecutionContext' cannot be found

Spring Batch Partitioning inject stepExecutionContext parameter in itemReader

But still I am getting exception:

Caused by: org.springframework.expression.spel.SpelEvaluationException: EL1008E:(pos 0): Property or field 'stepExecutionContext' cannot be found on object of type 'org.springframework.beans.factory.config.BeanExpressionContext' - maybe not public?
    at org.springframework.expression.spel.ast.PropertyOrFieldReference.readProperty(PropertyOrFieldReference.java:224)
    at org.springframework.expression.spel.ast.PropertyOrFieldReference.getValueInternal(PropertyOrFieldReference.java:94)
    at org.springframework.expression.spel.ast.PropertyOrFieldReference.getValueInternal(PropertyOrFieldReference.java:81)
    at org.springframework.expression.spel.ast.CompoundExpression.getValueRef(CompoundExpression.java:51)
    at org.springframework.expression.spel.ast.CompoundExpression.getValueInternal(CompoundExpression.java:87)
    at org.springframework.expression.spel.ast.SpelNodeImpl.getValue(SpelNodeImpl.java:120)
    at org.springframework.expression.spel.standard.SpelExpression.getValue(SpelExpression.java:242)
    at org.springframework.context.expression.StandardBeanExpressionResolver.evaluate(StandardBeanExpressionResolver.java:161)
    ... 19 more

My Itemreader file is something like this:

@Configuration
public class ProfileJobItemReader{

    @Value("#{stepExecutionContext[fromId]}")
    private int fromId;

    @Bean(name = "profileMongoItemReader")
    @StepScope
    public ItemReader<ProfileCollection> profileMongoItemReader()
            throws Exception, UnexpectedInputException, ParseException, NonTransientResourceException {

        System.out.println(fromId);
    }

}

And my xml file is something like this:

<bean id="profileItemProcessor" class="...........ProfileProcessor" scope="step" />
<bean id="profileItemWriter" class="...........ProfileWriter" scope="step" />

.............

<bean id="rangePartitioner" class="...........ProfilePartitioner" />

<batch:job id="profileJob">
    <batch:step id="masterStep">
        <partition step="profileMainStep" partitioner="rangePartitioner">
            <handler grid-size="100" task-executor="taskExecutor" />
        </partition>
    </batch:step>
</batch:job>

<batch:step id="profileMainStep">
    <batch:tasklet task-executor="profileTaskExecutor" throttle-limit="30">
        <batch:chunk reader="profileMongoItemReader" processor="profileItemProcessor"
            writer="profileItemWriter" commit-interval="${profileCommitInterval}" />
    </batch:tasklet>
</batch:step>

I am aware that I am getting exception because of below line in my item reader:

@Value("#{stepExecutionContext[fromId]}")

But the same statement is valid in my Processor class (getting results). So I am wondering what I am missing in my ItemReader class. Please help

No exception in Processor class. My processor class is like:

public class ProfileProcessor implements ItemProcessor<ProfileCollection, ProfileCollection> {

    @Value("#{stepExecutionContext[name]}")
    private String threadName;

    @Override
    public ProfileCollection process(ProfileCollection item) throws Exception {
        System.out.println(threadName);
Shashank
  • 712
  • 15
  • 33

2 Answers2

0

The problem is @Configuration annotation in your reader. Configuration class loads before job starts.

You will get stepExecutionContext only after starting a step. Your processor class gets stepExecutionContext because it doesn't have component/configuration annotation.

Binu
  • 754
  • 6
  • 15
0

The problem is that the stepExecutionContext is only defined inside @StepScope hence you can only access it inside the stepSope only, as below:

@Configuration
public class ProfileJobItemReader{

@Bean(name = "profileMongoItemReader")
@StepScope
public ItemReader<ProfileCollection> profileMongoItemReader(@Value("#{stepExecutionContext[fromId]}") int fromId)
        throws Exception, UnexpectedInputException, ParseException, NonTransientResourceException {

    System.out.println(fromId);

   }
}

And from the caller method you can pass null which will be ignored with your stepExecutionContext value.

Sandeep Kumar
  • 2,397
  • 5
  • 30
  • 37