I'm using spring batch for everyday jobs. It reads csv files then filling DB. I need to fill another DB with information about scv file in afterJob method.
This is configuration class.
@EnableBatchProcessing
@Configuration
public class BatchConfiguration {
@Autowired
public JobBuilderFactory jobs;
@Autowired
public StepBuilderFactory steps;
@Value("file://VMCOLLECTOR2/DataIn/mmvb_bonds_201803*.csv")
private Resource[] bondResources;
@Autowired
@Qualifier("hikariDataSource")
private DataSource dataSource;
@Bean
public Step bondEndOfDateStep() {
return steps.get("bondEndOfDateStep")
.<BondEndOfDateModel, BondEndOfDateModel> chunk(1000)
.reader(multiResourceItemReader())
.listener(new BondEndOfDateItemWriteListener())
.writer(writer(dataSource))
.build();
}
...
Once my application starts it works pretty. Every data is being written in BD and dataSource is autowired well. Then invokes afterJob method:
public class BondEndOfDateAfterJob extends JobExecutionListenerSupport {
@Autowired
@Qualifier("hikariDataSource")
private DataSource dataSource;
@Override
public void afterJob(JobExecution jobExecution) {
try (Connection connection = dataSource.getConnection()) {
} catch (SQLException e) {
e.printStackTrace();
}
}
}
In debug I can see that dataSource is null. It's not autowired. But in first case it was autowired. Here is log:
java.lang.NullPointerException: null
at SCV_Workflow.BondEndOfDateAfterJob.afterJob(BondEndOfDateAfterJob.java:20) ~[classes/:na]
at org.springframework.batch.core.listener.CompositeJobExecutionListener.afterJob(CompositeJobExecutionListener.java:60) ~[spring-batch-core-4.0.0.M1.jar:4.0.0.M1]
at org.springframework.batch.core.job.AbstractJob.execute(AbstractJob.java:352) ~[spring-batch-core-4.0.0.M1.jar:4.0.0.M1]
at org.springframework.batch.core.launch.support.SimpleJobLauncher$1.run(SimpleJobLauncher.java:141) [spring-batch-core-4.0.0.M1.jar:4.0.0.M1]
at org.springframework.core.task.SyncTaskExecutor.execute(SyncTaskExecutor.java:50) [spring-core-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.batch.core.launch.support.SimpleJobLauncher.run(SimpleJobLauncher.java:134) [spring-batch-core-4.0.0.M1.jar:4.0.0.M1]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_131]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_131]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_131]
at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_131]
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:333) [spring-aop-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190) [spring-aop-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157) [spring-aop-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.batch.core.configuration.annotation.SimpleBatchConfiguration$PassthruAdvice.invoke(SimpleBatchConfiguration.java:127) [spring-batch-core-4.0.0.M1.jar:4.0.0.M1]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) [spring-aop-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:213) [spring-aop-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at com.sun.proxy.$Proxy44.run(Unknown Source) [na:na]
at org.springframework.boot.autoconfigure.batch.JobLauncherCommandLineRunner.execute(JobLauncherCommandLineRunner.java:214) [spring-boot-autoconfigure-1.5.2.RELEASE.jar:1.5.2.RELEASE]
at org.springframework.boot.autoconfigure.batch.JobLauncherCommandLineRunner.executeLocalJobs(JobLauncherCommandLineRunner.java:231) [spring-boot-autoconfigure-1.5.2.RELEASE.jar:1.5.2.RELEASE]
at org.springframework.boot.autoconfigure.batch.JobLauncherCommandLineRunner.launchJobFromProperties(JobLauncherCommandLineRunner.java:123) [spring-boot-autoconfigure-1.5.2.RELEASE.jar:1.5.2.RELEASE]
at org.springframework.boot.autoconfigure.batch.JobLauncherCommandLineRunner.run(JobLauncherCommandLineRunner.java:117) [spring-boot-autoconfigure-1.5.2.RELEASE.jar:1.5.2.RELEASE]
at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:776) [spring-boot-1.5.2.RELEASE.jar:1.5.2.RELEASE]
at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:760) [spring-boot-1.5.2.RELEASE.jar:1.5.2.RELEASE]
at org.springframework.boot.SpringApplication.afterRefresh(SpringApplication.java:747) [spring-boot-1.5.2.RELEASE.jar:1.5.2.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:315) [spring-boot-1.5.2.RELEASE.jar:1.5.2.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1162) [spring-boot-1.5.2.RELEASE.jar:1.5.2.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1151) [spring-boot-1.5.2.RELEASE.jar:1.5.2.RELEASE]
at SCV_Workflow.ParserApplication.main(ParserApplication.java:10) [classes/:na]
Here is dataSource Config Class:
@Configuration
public class HikariDS {
@Bean
@Primary
@ConfigurationProperties(prefix = "datasource.infoserver")
public DataSourceProperties dataSourceProperties(){
return new DataSourceProperties();
}
@Bean(name = "hikariDataSource")
@Primary
public DataSource hikariDataSource() {
DataSourceProperties dataSourceProperties = dataSourceProperties();
HikariDataSource dataSource = new HikariDataSource();
dataSource.setMaximumPoolSize(20);
dataSource.setDataSourceClassName(dataSourceProperties.getDriverClassName());
dataSource.addDataSourceProperty("url", dataSourceProperties.getUrl());
dataSource.addDataSourceProperty("user", dataSourceProperties.getUsername());
dataSource.addDataSourceProperty("password", dataSourceProperties.getPassword());
dataSource.setInitializationFailFast(true);
dataSource.setPoolName("springHikariPool");
return dataSource;
}
}
Application works pretty except this detail that I very need.