Duncan McGregor
Duncan McGregor

Reputation: 18167

How do I invoke a method on an existing object with Quartz?

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?

Upvotes: 0

Views: 3855

Answers (4)

Duncan McGregor
Duncan McGregor

Reputation: 18167

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)
        }
    }
}

Upvotes: 1

ᴇʟᴇvᴀтᴇ
ᴇʟᴇvᴀтᴇ

Reputation: 12751

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.

Upvotes: 0

Dinesh
Dinesh

Reputation: 180

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();

Upvotes: 1

M4ver1k
M4ver1k

Reputation: 1575

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.

Upvotes: 1

Related Questions