I managed to configure and schedule a Quartz job using JobStoreTX persistent store in Spring Boot ( version 4.2.5 ). Here is how I schedule the job. First :
public class MyJob implements Job{
@Autowired
IService service;
@Override
public void execute(JobExecutionContext context) throws JobExecutionException {
service.doSomething();
}
}
@Autowired
seems like it wont work in a Quartz job implementation because it wont be instantiated by Spring. Hence, im facing the famous JavaNullPointerException.
Second, in order to get hold of Spring-managed beans in a Quartz job, I used org.springframework.scheduling.quartz.SchedulerFactoryBean
to manage the Quartz lifecycle :
public class MyJob implements Job{
@Override
public void execute(JobExecutionContext context) throws JobExecutionException {
try {
ApplicationContext applicationContext = (ApplicationContext) context.getScheduler().getContext().get("applicationContext");
IService service= applicationContext.getBean(IService.class);
service.getManualMaxConfig();
} catch (SchedulerException e) {
e.printStackTrace();
}
}
}
And then :
<bean id="scheduler"
class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="applicationContextSchedulerContextKey" value="applicationContext" />
</bean>
The sad news is that im also facing JavaNPE. I also try these suggestions, in vain ..
Whats wrong with what im doing?
Update 1 : Before trying to inject service, i tried to pass some Params as @ritesh.garg suggests.
public class MyJob implements Job{
private String someParam;
private int someParam2;
public void setSomeParam(String someParam) {
this.someParam = someParam;
}
public void setSomeParam2(int someParam2) {
this.someParam2 = someParam2;
}
@Override
public void execute(JobExecutionContext context) throws JobExecutionException {
System.out.println("My job is running with "+someParam+' '+someParam2);
}
}
And my jobBean.xml looks like :
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="scheduler"
class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="applicationContextSchedulerContextKey" value="applicationContext" />
</bean>
<bean id="myJob" class="org.springframework.scheduling.quartz.JobDetailFactoryBean">
<property name="jobClass" value="com.quartz.service.MyJob"/>
<property name="jobDataAsMap">
<map>
<entry key="someParam" value="some value"/>
<entry key="someParam2" value="1"/>
</map>
</property>
</bean>
</beans>
I dont know why, but the parameters arent passed and it prints :
My job is running with null 0
Ps : I imported the jobBean.xml into Application.java . So i dont know what am i missing ?
Update 2 : Here is my detailed code :
@Component
public class JobScheduler{
Timer timer = new Timer();
@PostConstruct
public void distributeAutomaticConf(){
try {
timer.schedule(new ServiceImpl(), 10000);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Service Impl :
@Transactional
@Component
public class ServiceImpl extends TimerTask implements IService{
@Override
public void run() {
final SchedulerFactory factory = new StdSchedulerFactory();
Scheduler scheduler = null;
try {
scheduler = factory.getScheduler();
final JobDetailImpl jobDetail = new JobDetailImpl();
jobDetail.setName("My job executed only once.. ");
jobDetail.setJobClass(MyJob.class);
SimpleTrigger trigger = (SimpleTrigger) newTrigger()
.withIdentity("trigger_", "group_")
.build();
scheduler.start();
scheduler.scheduleJob(jobDetail, trigger);
System.in.read();
if (scheduler != null) {
scheduler.shutdown();
}
} catch (final SchedulerException e) {
e.printStackTrace();
} catch (final IOException e) {
e.printStackTrace();
}
}
}
MyJob :
public class MyJob extends QuartzJobBean{
@Autowired
IService service;
@Override
protected void executeInternal(JobExecutionContext arg0) throws JobExecutionException { SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this);
service.doSomething();
}
}
jobBean.xml :
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="scheduler"
class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="applicationContextSchedulerContextKey" value="applicationContext" />
</bean>
<bean id="myJob" class="org.springframework.scheduling.quartz.JobDetailFactoryBean">
<property name="jobClass" value="com.quartz.service.MyJob"/>
<property name="jobDataAsMap">
<map>
<entry key="someParam" value="some value"/>
<entry key="someParam2" value="1"/>
</map>
</property>
</bean>
</beans>
quartz.properties :
org.quartz.scheduler.instanceName = DefaultQuartzScheduler
org.quartz.scheduler.rmi.export = false
org.quartz.scheduler.rmi.proxy = false
org.quartz.scheduler.wrapJobExecutionInUserTransaction = false
org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount = 10
org.quartz.threadPool.threadPriority = 5
org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread = true
org.quartz.jobStore.misfireThreshold = 60000
org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.PostgreSQLDelegate
#org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate
org.quartz.jobStore.dataSource = myDS
org.quartz.jobStore.tablePrefix = QRTZ_
org.quartz.dataSource.myDS.driver = org.postgresql.Driver
org.quartz.dataSource.myDS.URL = jdbc:postgresql://localhost:5432/myDB
org.quartz.dataSource.myDS.user = admin
org.quartz.dataSource.myDS.password = admin
org.quartz.dataSource.myDS.maxConnections = 10
org.quartz.scheduler.skipUpdateCheck=true
console :
java.lang.NullPointerException: null
at com.quartz.service.MyJob.executeInternal(MyJob.java:27) ~[classes/:na]
at org.springframework.scheduling.quartz.QuartzJobBean.execute(QuartzJobBean.java:113) ~[spring-context-support-3.1.2.RELEASE.jar:3.1.2.RELEASE]
at org.quartz.core.JobRunShell.run(JobRunShell.java:202) ~[quartz-2.2.1.jar:na]
at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:573) [quartz-2.2.1.jar:na]
2016-06-05 11:35:16.839 ERROR 25452 --- [eduler_Worker-1] org.quartz.core.ErrorLogger : Job (DEFAULT.My job executed only once.. threw an exception.
org.quartz.SchedulerException: Job threw an unhandled exception.
at org.quartz.core.JobRunShell.run(JobRunShell.java:213) ~[quartz-2.2.1.jar:na]
at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:573) [quartz-2.2.1.jar:na]
Caused by: java.lang.NullPointerException: null
at com.quartz.service.MyJob.executeInternal(MyJob.java:27) ~[classes/:na]
at org.springframework.scheduling.quartz.QuartzJobBean.execute(QuartzJobBean.java:113) ~[spring-context-support-3.1.2.RELEASE.jar:3.1.2.RELEASE]
at org.quartz.core.JobRunShell.run(JobRunShell.java:202) ~[quartz-2.2.1.jar:na]
... 1 common frames omitted