I've configured quartz job in jHipster server and it is working fine for System.out.println
statement but when I try to use persistence related work It's giving me an exception. I've @Autowire
JdbcTemplate jdbcTemplate; but it's still null and the reason is when the jHipster server runs it tells that :
Scheduler meta-data: Quartz Scheduler (v2.2.1) 'schedulerFactoryBean' with instanceId **'NON_CLUSTERED'**
Scheduler class: 'org.quartz.core.QuartzScheduler' - **running locally**.
NOT STARTED.
Currently in standby mode.
Number of jobs executed: 0
Using thread pool 'org.quartz.simpl.SimpleThreadPool' - with 10 threads.
Using job-store 'org.quartz.simpl.RAMJobStore' - **which does not support persistence. and is not clustered**.
2017-09-26 10:56:10.523 INFO 10188 --- [ restartedMain] org.quartz.impl.StdSchedulerFactory : Quartz scheduler **'schedulerFactoryBean' initialized from an externally provided properties** instance.
2017-09-26 10:56:10.523 INFO 10188 --- [ restartedMain] org.quartz.impl.StdSchedulerFactory : Quartz scheduler version: 2.2.1
2017-09-26 10:56:10.523 INFO 10188 --- [ restartedMain] org.quartz.core.QuartzScheduler : JobFactory set to: org.springframework.scheduling.quartz
These are the logs that jhipster prints and please tell how can I use persistence with jdbcTemplet I do not want open a separate JDBC connection. If possible I would like to use the existing service class but that also gives an error.
Here are my configuration file and job file
@Configuration
@ComponentScan("com.jobs")
public class QuartzJobSchedulerConf {
//http://www.concretepage.com/spring-4/spring-4-quartz-2-scheduler integration-annotation-example-using-javaconfig
//todo make common function for simple jobs to set attributes
//todo make common function for complex jobs to set attributes
@Bean //this is simple job1
public MethodInvokingJobDetailFactoryBean methodInvokingJobDetailFactoryBean() {
MethodInvokingJobDetailFactoryBean obj = new MethodInvokingJobDetailFactoryBean();
obj.setTargetBeanName("jobone");
obj.setTargetMethod("myTask");
return obj;
}
@Bean
public SimpleTriggerFactoryBean simpleTriggerFactoryBean(){
//This trigger will schedule the job after 3 seconds and repeat after every 30 seconds for 3+1 times.
SimpleTriggerFactoryBean stFactory = new SimpleTriggerFactoryBean();
stFactory.setJobDetail(methodInvokingJobDetailFactoryBean().getObject());
stFactory.setStartDelay(3000);
stFactory.setRepeatInterval(30000);
stFactory.setRepeatCount(3);//todo repeat counter remove or use
return stFactory;
}
@Bean //this is simple job2
public MethodInvokingJobDetailFactoryBean methodInvokingJobDetailFactoryBean2() {
MethodInvokingJobDetailFactoryBean obj = new MethodInvokingJobDetailFactoryBean();
obj.setTargetBeanName("jobtwo");
obj.setTargetMethod("myTask");
return obj;
}
@Bean
public SimpleTriggerFactoryBean simpleTriggerFactoryBean2(){
SimpleTriggerFactoryBean stFactory = new SimpleTriggerFactoryBean();
stFactory.setJobDetail(methodInvokingJobDetailFactoryBean2().getObject());
stFactory.setStartDelay(3000);
stFactory.setRepeatInterval(30000);
stFactory.setRepeatCount(3);//todo repeat counter remove or use
return stFactory;
}
@Bean//this is complex job1
public JobDetailFactoryBean jobDetailFactoryBean(){
/*To pass the parameter to job by JavaConfig, we can have setter method and
the property should be configured with setJobDataAsMap() in JobDetailFactoryBean
configuration in JavaConfig*/
JobDetailFactoryBean factory = new JobDetailFactoryBean();
factory.setJobClass(SampleComplexJob.class);
Map<String,Object> map = new HashMap<String,Object>();
map.put("name", "RAM");
map.put(SampleComplexJob.COUNT, 1);
factory.setJobDataAsMap(map);
factory.setGroup("mygroup");
factory.setName("myjob");
return factory;
}
@Bean
public CronTriggerFactoryBean cronTriggerFactoryBean(){
CronTriggerFactoryBean stFactory = new CronTriggerFactoryBean();
stFactory.setJobDetail(jobDetailFactoryBean().getObject());
stFactory.setStartDelay(3000);
stFactory.setName("mytrigger");
stFactory.setGroup("mygroup");
stFactory.setCronExpression("0 0/1 * 1/1 * ? *");
return stFactory;
}
@Bean
public SchedulerFactoryBean schedulerFactoryBean() {
SchedulerFactoryBean scheduler = new SchedulerFactoryBean();
scheduler.setTriggers(simpleTriggerFactoryBean().getObject(),
simpleTriggerFactoryBean2().getObject(),
cronTriggerFactoryBean().getObject());
return scheduler;
}
}
There is the job Class code
/*If we want to persist the changes in JobDataMap, we will annotate our class by @PersistJobDataAfterExecution */
@PersistJobDataAfterExecution
/*if there is more than one trigger which are scheduling same job then to avoid race condition, we have to annotate our job with @DisallowConcurrentExecution.*/
@DisallowConcurrentExecution
public class SampleComplexJob extends QuartzJobBean {
@Autowired
JdbcTemplate jdbcTemplate;
public static final String COUNT = "count";
private String name;
protected void executeInternal(JobExecutionContext ctx) throws JobExecutionException {
for(String role:findRoleByPrivilegeSQLExample("PRIV_USER_SETTING")){
System.out.println(role);
}
JobDataMap dataMap = ctx.getJobDetail().getJobDataMap();
int cnt = dataMap.getInt(COUNT);
JobKey jobKey = ctx.getJobDetail().getKey();
System.out.println(jobKey+": "+name+": "+ cnt);
cnt++;
dataMap.put(COUNT, cnt);
}
public void setName(String name) {
this.name = name;
}
public List<String> findRoleByPrivilegeSQLExample(String privilege){
///this is SQL example
List<String> rolePrivilegesList = new ArrayList<String>();
if(!privilege.isEmpty()){
StringBuilder sql=new StringBuilder()
.append("SELECT ID_ROLE FROM ROLE_PRIVILEGES WHERE ")
.append("UPPER(ID_PRIVILEGE) = '")
.append(privilege.toUpperCase()).append("'");
rolePrivilegesList = jdbcTemplate.queryForList(sql.toString(),String.class);
}
return rolePrivilegesList;
}
}
If there is another way to configure Quartz job in jHipster please tell me. Or if jHipster gives out of the box functionality for Scheduler work then It would be great.
Quartz job Dependency
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.2.1</version>
</dependency>