Java Spring Batch - файл ресурсов не внедряется в тасклет - PullRequest
0 голосов
/ 17 апреля 2020

Я делаю java примеры из книги «Spring Batch In Action», глава 1. В этом примере таскет распаковывает zip-файл. Тасклет получает путь к файлу 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();
   }

}

Файл products.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 голос
/ 21 апреля 2020

В вашем определении работы у вас есть:

@Bean
public Job job(JobBuilderFactory jobBuilderFactory) {

    return jobBuilderFactory
            .get("importProductsJob")
            .start(descompressStep.stepDescompress())
            .next(readWriteProductStep.stepReaderWriter())
            .incrementer(new RunIdIncrementer())
            .build();
}

То, как вы передаете шаги к start и next методам, неверно (я даже не вижу, как это скомпилируется). Что вы можете сделать, так это импортировать классы конфигурации шагов и внедрить оба шага в определение задания. Что-то вроде:

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

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...