I'm doing the java examples from the book Spring Batch In Action chapter 1. In this example, a tasket unzips a zip file. The tasklet receives the zip file path as a job parameter. I implemented a test method that runs the job and passes the parameters.
@StepScope
@Component
public class DecompressTasklet implements Tasklet {
private static final Logger LOGGER = LogManager.getLogger(DecompressTasklet.class);
@Value("#{jobParameters['inputResource']}")
private Resource inputResource;
@Value("#{jobParameters['targetDirectory']}")
private String targetDirectory;
@Value("#{jobParameters['targetFile']}")
private String targetFile;
@Override
public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {
//code here
}
}
@Configuration
public class DescompressStep {
@Autowired
private StepBuilderFactory stepBuilderFactory;
@Autowired
private DecompressTasklet decompressTasklet;
@Bean
public Step stepDescompress() {
return stepBuilderFactory
.get(DescompressStep.class.getSimpleName())
.tasklet(decompressTasklet)
.build();
}
}
@EnableBatchProcessing
@Configuration
public class ImportProductsJob {
@Autowired
private DescompressStep descompressStep;
@Autowired
private ReadWriteProductStep readWriteProductStep;
@Bean
public Job job(JobBuilderFactory jobBuilderFactory) {
return jobBuilderFactory
.get("importProductsJob")
.start(descompressStep.stepDescompress())
.next(readWriteProductStep.stepReaderWriter())
.incrementer(new RunIdIncrementer())
.build();
}
}
Below is the test code that runs the job
@RunWith(SpringRunner.class)
@SpringBootTest
@SpringBatchTest
@AutoConfigureTestDatabase
public class ImportProductsIntegrationTest {
@Autowired
private JobRepositoryTestUtils jobRepositoryTestUtils;
@Autowired
private JobLauncherTestUtils jobLauncherTestUtils;
@After
public void cleanUp() {
jobRepositoryTestUtils.removeJobExecutions();
}
@Test
public void importProducts() throws Exception {
jobLauncherTestUtils.launchJob(defaultJobParameters());
}
private JobParameters defaultJobParameters() {
JobParametersBuilder paramsBuilder = new JobParametersBuilder();
paramsBuilder.addString("inputResource", "classpath:input/products.zip");
paramsBuilder.addString("targetDirectory", "./target/importproductsbatch/");
paramsBuilder.addString("targetFile", "products.txt");
paramsBuilder.addLong("timestamp", System.currentTimeMillis());
return paramsBuilder.toJobParameters();
}
}
The products.zip file is in src/main/resources/input The problem is that when running the test the error occurs
java.lang.NullPointerException: null
at com.springbatch.inaction.ch01.DecompressTasklet.execute(DecompressTasklet.java:62) ~[classes/:na]
I verified that the inputResource property is null. Why does this error occur?
In your job definition, you have:
@Bean
public Job job(JobBuilderFactory jobBuilderFactory) {
return jobBuilderFactory
.get("importProductsJob")
.start(descompressStep.stepDescompress())
.next(readWriteProductStep.stepReaderWriter())
.incrementer(new RunIdIncrementer())
.build();
}
The way you are passing steps to start
and next
methods is incorrect (I don't even see how this would compile). What you can do is import step configuration classes and inject both steps in your job definition. Something like:
@EnableBatchProcessing
@Configuration
@Import({DescompressStep.class, ReadWriteProductStep.class})
public class ImportProductsJob {
@Bean
public Job job(JobBuilderFactory jobBuilderFactory,
Step stepDescompress, Step stepReaderWriter) {
return jobBuilderFactory
.get("importProductsJob")
.start(stepDescompress)
.next(stepReaderWriter)
.incrementer(new RunIdIncrementer())
.build();
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.