0

I have a object, nicely configured with everything it needs to do its job. If I could just call run() on it once a day, my life would be complete.

To be clear, I know how to create a schedule and a trigger. But the methods to schedule all take JobDetail, which wants to create a new instance of my class. How do I use the one that I have?

In short, is there a nice way without Spring to call a method on my object using Quartz?

Duncan McGregor
  • 17,665
  • 12
  • 64
  • 118
  • 2
    I don't know if you are using some framework to run your object and the scheduled Quartz jobs like Spring. Let's asume that you aren't. What about using the Singleton pattern to recover an instance of your object? – RubioRic Mar 24 '16 at 09:01
  • Spring has MethodInvokingJobDetailFactoryBean. Another option may be creating job class that take your object (from job data or something) and call it. – BobTheBuilder Mar 24 '16 at 09:02
  • If you are using Spring, there are a lot of possible solutions here http://stackoverflow.com/questions/6990767/inject-bean-reference-into-a-quartz-job-in-spring – RubioRic Mar 24 '16 at 09:12

4 Answers4

1

If you are using Quartz with Spring you can do the following :

Sample code

 MethodInvokingJobDetailFactoryBean jobDetailfactory = new MethodInvokingJobDetailFactoryBean();
 jobDetailfactory.setTargetObject(configuredObject);
 jobDetailfactory.setTargetMethod("methodName");

Here configuredObject is your nicely configured object and methodName is the name of the method to be invoked. You can autowire the configuredObject into this class.

M4ver1k
  • 1,505
  • 1
  • 15
  • 26
1

You can use Quartz JobBuilder to build Quartz JobDetail Object using your own jobDetails class, if I get you correctly. let me know if it is not required by you.

Suppose Job info is your own class having jobdetails. then you can use it below like this:

JobDataMap jobDataMap = new JobDataMap();

Map<String, Object> jobParams = jobInfo.getJobParams();
for (String paramKey : jobParams.keySet()) {
  jobDataMap.put(paramKey, jobParams.get(paramKey));
}

jobBuilder.ofType((Class<? extends Job>) Class.forName(jobInfo.getJobClass()))
    .withIdentity(jobInfo.getName(), jobInfo.getGroup())
    .withDescription(jobInfo.getDescription()).storeDurably(jobInfo.isStoreDurably())
    .usingJobData(jobDataMap);

JobDetail jobDetail = jobBuilder.build();
Dinesh
  • 160
  • 1
  • 2
  • 13
1

Here's some code (Kotlin)

fun createJobDetail(jobName: String, function: () -> Unit)  = JobBuilder.newJob(MyJob::class.java)
    .withIdentity(jobName)
    .usingJobData(JobDataMap(mapOf(jobDataKey to function)))
    .build()`

@DisallowConcurrentExecution
class MyJob : Job {
    @Suppress("UNCHECKED_CAST")
    override fun execute(context: JobExecutionContext) {
        try {
            (context.jobDetail.jobDataMap[jobDataKey] as () -> Unit)()
        } catch(e: Exception) {
            throw JobExecutionException(e)
        }
    }
}
Duncan McGregor
  • 17,665
  • 12
  • 64
  • 118
0

Instead of using Quartz, you might be better off using the built-in java.util.concurrent. ScheduledExecutorService and its scheduleAtFixedRate() method.

For example:

ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1,
        new ThreadFactory() {

            @Override
            public Thread newThread(Runnable runnable) {
                Thread t = Executors.defaultThreadFactory().newThread(runnable);
                t.setDaemon(true);
                return t;
            }
        });


scheduler.scheduleAtFixedRate(new Runnable() {

        @Override
        public void run() {
            myLovelyObject.run();
        }
    }, 0, 24, TimeUnit.HOURS);

If you need to use Quartz, you could always store a reference to your object in a static field in the Job class. Not elegant, but not exactly the end of the world either.

ᴇʟᴇvᴀтᴇ
  • 12,285
  • 4
  • 43
  • 66
  • It's the cron pattern parsing that I need! – Duncan McGregor Jun 27 '16 at 12:38
  • Take a look at [`org.quartz.CronExpression`](https://github.com/quartz-scheduler/quartz/blob/master/quartz-core/src/main/java/org/quartz/CronExpression.java). The cron pattern parsing is entirely self-contained. You could even just copy that one class into your project. – ᴇʟᴇvᴀтᴇ Jun 27 '16 at 17:02