How to remove job in Quartz JDBC Store? - java

I wrote this method to remove a job from Quartz JDBC
public boolean removeJob(String jobName) {
try {
JobKey jobKey = JobKey.jobKey(jobName);
try {
Scheduler sched = schedulerFactoryBean.getScheduler();
logger.info("RESULT: " + sched.deleteJob(jobKey));
} catch (Exception e) {
throw new RuntimeException(e);
}
return true;
} catch (Exception ex) {
logger.error(ex.getMessage());
return false;
}
}
deleteJob is always returning false. So the job is not getting removed from the JDBC tables in mysql. What am I doing wrong. I only want to completely remove this job from the scheduler

Have you defined a job group during job creation? Then you may need to call jobKey(jobName, group). You can also check if job exists with scheduler.checkExists(jobKey) method which will be good for debugging.
JobKey jobKey = jobKey(jobName, group);
if (scheduler.checkExists(jobKey)) {
logger.info("job found with key: {}", jobKey);
scheduler.deleteJob(jobKey);
}

Related

Using DAO classes for data call in Cron Job

Hi this is my Cron Scheduler
public class CronListener implements ServletContextListener {
Scheduler scheduler = null;
#Override
public void contextInitialized(ServletContextEvent servletContext) {
System.out.println("Context Initialized");
try {
// Setup the Job class and the Job group
JobDetail job = newJob(CronJob.class).withIdentity("CronQuartzJob",
"Webapp").build();
// This is what I've tried as well
/*
* JobDataMap jdm = new JobDataMap(); jdm.put("targetDAO",
* targetDAO);
*/
// Create a Trigger that fires every X minutes.
Trigger trigger = newTrigger()
.withIdentity("CronQuartzJob", "Sauver")
.withSchedule(
CronScheduleBuilder.cronSchedule
("0 0/1 * 1/1 * ? *")).build();
// Setup the Job and Trigger with Scheduler & schedule jobs
scheduler = new StdSchedulerFactory().getScheduler();
scheduler.start();
scheduler.scheduleJob(job, trigger);
} catch (SchedulerException e) {
e.printStackTrace();
}
}
#Override
public void contextDestroyed(ServletContextEvent servletContext) {
System.out.println("Context Destroyed");
try {
scheduler.shutdown();
} catch (SchedulerException e) {
e.printStackTrace();
}
}
}
And here's the Cron Job itself
public class CronJob implements org.quartz.Job {
static Logger log = Logger.getLogger(CronJob.class.getName());
#Autowired
TargetDAO targetDAO;
#Override
public void execute(JobExecutionContext context)
throws JobExecutionException {
try {
targetDAO.getAllTargets();
} catch (Exception e1) {
e1.printStackTrace();
}
log.info("webapp-rest cron job started");
try {
Utils.getProcessed();
} catch (Exception e) {
e.printStackTrace();
}
}
What I'm trying to do is getting a DAO class to call some data into it and call a function through it, every few hours.
But when I call data through the DAO, it always returns empty.
What I've found is that I must map the DAO somehow, I've seen in xml-based cron jobs, but I am unable to map it in this one.
This not exactly an answer, but a workaround,
What I did was made a new class
#EnableScheduling
#Component
public class SpringCronJob {
private static Logger log = Logger.getLogger(SpringCronJob.class.getName());
#Autowired
TargetDAO targetDAO;
#Scheduled(fixedRate = 15000)
public void getPostedTargets() {
try {
log.info(targetDAO.getAllTargets());
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
It doesn't need anything else, no scheduler, you just need to add it to your component scan
This is what lead me to it
http://howtodoinjava.com/spring/spring-core/4-ways-to-schedule-tasks-in-spring-3-scheduled-example/

Quartz scheduler missing job

I am adding a job to quartz scheduler. After that I call the attached debug print jobs function. It does not list the job. Is the function call to getCurrentlyExecutingJobs() maybe limited to return max. of 10 jobs?
public void scheduleManagementEmail(ManagementEmailConfig managementEmailConfig, Scheduler scheduler) throws SchedulerException
{
logger.debug("Scheduling Management Email " +
managementEmailConfig.getManagementEmailConfigId());
String jobKey = "SendManagementEmailJob_" +
managementEmailConfig.getManagementEmailConfigId();
Class<? extends Job> jobClass = SendManagementEmailJob.class;
JobDetail job = JobBuilder.newJob(jobClass).withIdentity(new JobKey(jobKey)).build();
Trigger trigger = sendManagementEmailJob.getTriggerWithSchedule(managementEmailConfig);
trigger.getJobDataMap().put("managementEmailConfigId", managementEmailConfig.getManagementEmailConfigId());
if (!scheduler.checkExists(new JobKey(jobKey)))
{
scheduler.scheduleJob(job, trigger);
}
debugPrintJobs();
}
public void debugPrintJobs() {
try {
logger.debug("Quartz Jobs");
Scheduler s_scheduler = this.getJobScheduler();
List<JobExecutionContext> currentJobs = s_scheduler.getCurrentlyExecutingJobs();
for (JobExecutionContext jobCtx : currentJobs) {
JobKey jobKey = jobCtx.getJobDetail().getKey();
JobDetail jobDetail = s_scheduler.getJobDetail(jobKey);
List<? extends Trigger> triggers = s_scheduler.getTriggersOfJob(jobKey);
Date nextFireTime = null;
if (triggers.size() > 0)
{
nextFireTime = triggers.get(0).getNextFireTime();
}
logger.debug("Name= "+ jobKey.getName() + " Group=" + jobKey.getGroup() + " NextFireTime=" + nextFireTime);
}
} catch (Exception e) {
logger.debug("debugPrintJobs:" + e.getMessage());
}
The method getCurrentlyExecutingJobs() will return only the jobs that are running, not every scheduled job.
To get every scheduled job, you should do something like this:
Scheduler scheduler = getScheduler();
try {
// All scheduled jobs
for (String groupName : scheduler.getJobGroupNames()) {
for (JobKey jobKey : scheduler.getJobKeys(GroupMatcher.jobGroupEquals(groupName))) {
JobDetail jobDetail = scheduler.getJobDetail(jobKey);
final List<? extends Trigger> triggersOfJob = scheduler.getTriggersOfJob(jobKey);
// Do something with the info you just got
// ...
}
}
} catch (SchedulerException e) {
log.error("Retrieving jobs", e);
}

Tapestry Hibernate session closed after exceeding ExecutorService fixed thread pool

I'm a tapestry-hibernate user and I'm experiencing an issue where my session remains closed once I exceed my Executors.newFixedThreadPool(1);
I have the following code which will work perfectly for the first thread while the remaining threads experience a closed session. If I increase the thread pool to 10, all the threads will run without issue. As soon as I exceed the fixedThreadPool, I get the session closed exception. I do not know how to open it since it's managed by tapestry-hibernate. If I use newCachedThreadPool, everything works perfectly. Does anybody know what might be happening here?
public void setupRender() {
ExecutorService executorService = Executors.newFixedThreadPool(1);
final ConcurrentHashMap<String, Computer> map = new ConcurrentHashMap<>();
final String key = "myKey";
final Date date = new Date();
List<Future> futures = new ArrayList<>();
for (int i = 0; i < 10; i++) {
final int thread = i;
Future future = executorService.submit(new Callable() {
#Override
public String call() {
try {
Computer computer = new Computer("Test Computer thread");
computer = getComputer(map, key, key, computer);
Monitor monitor = new Monitor();
monitor.setComputer(computer);
session.save(monitor);
session.flush();
System.out.println("thread " + thread);
try {
sessionManager.commit();
} catch (HibernateException ex) {
sessionManager.abort();
} finally {
session.close();
}
} catch (Exception ex) {
System.out.println("ex " + ex);
}
System.out.println( new Date().getTime() - date.getTime());
return "completed";
}
});
futures.add(future);
}
for(Future future : futures) {
try {
System.out.println(future.get());
} catch (InterruptedException | ExecutionException ex) {
Logger.getLogger(MultiThreadDemo.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
public synchronized Computer getComputer(ConcurrentHashMap<String, Computer> map, String key, String thread, Computer computer) {
if (map.putIfAbsent(key, computer) == null) {
session.save(computer);
} else {
computer = map.get(key);
}
return computer;
}
I've told you this before.... you MUST either use ParallelExecutor OR call PerThreadManager.cleanup(). You need to understand that tapestry-hibernate has PerThread scoped services that MUST be cleaned up if you are using them outside of a normal request/response (or ParallelExecutor).
I also don't think you should be calling session.close(). You should mimmic CommitAfterWorker.
It would probably look something like:
#Inject PerThreadManager perThreadManager;
#Inject HibernateSessionManager sessionManager; // this is a proxy to a per-thread value
#Inject Session session; // this is a proxy to a per-thread value
public void someMethod() {
ExecutorService executorService = ...;
executorService.submit(new Callable() {
public String call() {
try {
Monitor monitor = ...
session.save(monitor);
session.flush(); // optional
sessionManager.commit();
} catch (Exception ex) {
sessionManager.abort();
} finally {
// this allows Session and HibernateSessionManager to
// clean up after themselves
perThreadManager.cleanup();
}
return ...
}
});
}
If you choose to use the ParallelExecutor (and Invokable) instead of Executors.newFixedThreadPool(1) you can remove the references to PerThreadManager since it automatically cleans up the thread.

Quartz, How to start a job after another job finishes?

I'd like to use quartz for a project, but it seems to be missing some functionality. What I need is very simple, to fire another job after one finishes execution. This ideally would be done with a stored trigger, but quartz only considers time-based triggers, and no other kind. I'm looking for some kind of a job dependency system for quartz.
In reality there should be lots of triggers, such as other jobs finishing, files being modified, database tables being updated, etc.
Here's a job that waits for 5 seconds:
public class JobA implements Job, JobListener {
public static final String LISTENER_NAME = "JobA";
public void execute(JobExecutionContext arg0) throws JobExecutionException {
System.out.println("Job A, Waiting for 5 seconds");
try {
Thread.sleep(5L * 1000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Done waiting");
}
public String getName() {
return LISTENER_NAME;
}
public void jobExecutionVetoed(JobExecutionContext context) {
//TODO
}
public void jobToBeExecuted(JobExecutionContext context) {
String jobName = context.getJobDetail().getKey().toString();
System.out.println("Job : " + jobName + " is going to start...");
}
public void jobWasExecuted(JobExecutionContext context,
JobExecutionException jobException) {
// System.out.println("jobWasExecuted");
String jobName = context.getJobDetail().getKey().toString();
System.out.println("Job : " + jobName + " is finished...");
if (!jobException.getMessage().equals("")) {
System.out.println("Exception thrown by: " + jobName
+ " Exception: " + jobException.getMessage());
}
JobKey jobKey = new JobKey("JobA", "group1");
try {
context.getScheduler().triggerJob(jobKey);
} catch (SchedulerException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
The context.getScheduler().triggerJob(jobKey) line simply doesn't work. I've tried adding full jobs, recursive jobs, and can't seem to get anything to work. How can I get another job to fire while using this listener?

Quartz jobs are showing up even after deleting them. Do you know why?

I am seeing the scheduler returns the same job (scheduler.getCurrentlyExecutingJobs()) even after deleting it (scheduler.deleteJob(jobExCntxt.getJobDetail().getName(), jobExCntxt.getJobDetail().getGroup())). Am I doing the right thing? I wanted to remove that job and associated threads forever. Is that possible?
try {
List<JobExecutionContext> jobExCntxts = scheduler.getCurrentlyExecutingJobs();
if(jobExCntxts != null){
for(JobExecutionContext jobExCntxt: jobExCntxts){
if(jobExCntxt != null){
Date triggerTime = DateUtils.addMinutes(jobExCntxt.getTrigger().getPreviousFireTime(), 1);
if(triggerTime.before(Calendar.getInstance().getTime())){
System.out.println("Deleting a long living job !");
System.out.println("Delete return = " + scheduler.deleteJob(jobExCntxt.getJobDetail().getName(),
jobExCntxt.getJobDetail().getGroup()));
}
}
}
}
} catch (SchedulerException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Have you tried interrupt() the job? deleteJob() only removes the job from the job store.

Categories