有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

Java Spring批处理资源文件未注入tasklet

我正在做《Spring Batch In Action第1章》一书中的java示例。 在本例中,tasket解压zip文件。tasklet将zip文件路径作为作业参数接收。 我实现了一个测试方法,可以运行作业并通过参数

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


}

下面是运行作业的测试代码

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

}

产品。zip文件位于src/main/resources/input中 问题是运行测试时会出现错误

java.lang.NullPointerException: null
    at com.springbatch.inaction.ch01.DecompressTasklet.execute(DecompressTasklet.java:62) ~[classes/:na]

我验证了inputResource属性为null。为什么会出现这种错误


共 (1) 个答案

  1. # 1 楼答案

    在你的工作定义中,你有:

    @Bean
    public Job job(JobBuilderFactory jobBuilderFactory) {
    
        return jobBuilderFactory
                .get("importProductsJob")
                .start(descompressStep.stepDescompress())
                .next(readWriteProductStep.stepReaderWriter())
                .incrementer(new RunIdIncrementer())
                .build();
    }
    

    startnext方法传递步骤的方式是不正确的(我甚至不知道这将如何编译)。您可以做的是导入步骤配置类,并在作业定义中注入这两个步骤。比如:

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