Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Quartz JobDataMap doesn't work for not-primitive types

I have a following problem with Quartz JobDataMap. I expect that when using simple Quartz Job and passing not-primitive object (e.g. instance of StringBuilder) into JobDateMap, method execute (from my job) should be always invoked with different copy of objected I put. Unfortunately I always get instance of object I put into JobDateMap (like it would be a StatefulJob).

In bellow example I expect to get single '*' in every invocation while I get one more '*' every time.

public class MyJob implements Job {

    public static void main(String[] args) throws SchedulerException {

        SchedulerFactory schedFact = new StdSchedulerFactory();
        Scheduler sched = schedFact.getScheduler();

        JobDetail jobDetail = new JobDetail("job", Scheduler.DEFAULT_GROUP, MyJob.class);
        jobDetail.getJobDataMap().put("param", new StringBuilder());

        Trigger trigger = TriggerUtils.makeImmediateTrigger("trigger", 10, 100);
        trigger.setGroup(Scheduler.DEFAULT_GROUP);

        sched.scheduleJob(jobDetail, trigger);
        sched.start();

        try {
            Thread.sleep(1000L);
        } catch (Exception e) {}

        sched.shutdown(true);

    }

    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {
        StringBuilder sb = (StringBuilder) context.getMergedJobDataMap().get("param");
        sb.append("*");
        System.out.println(sb.toString());

    }
}

I think, I'm missing something about how Quartz is working. Anybody knows what?

like image 748
Paweł Adamski Avatar asked Dec 04 '22 00:12

Paweł Adamski


1 Answers

There are other facilities in Quartz that allow you to pass non-primitives in a more optimized fashion. Check out SchedulerContext class functionality.

using System;
using System.Text;
using Quartz;
using Quartz.Impl;

namespace QuartzNET.Samples
{
    class Program
    {
        static void Main(string[] args)
        {
            // Create RAMJobStore instance
            DirectSchedulerFactory.Instance.CreateVolatileScheduler(1);
            ISchedulerFactory factory = DirectSchedulerFactory.Instance;

            // Get scheduler and add object
            IScheduler scheduler = factory.GetScheduler();
            scheduler.Context.Add("History", new StringBuilder("Runtime History: "));

            // Create job and trigger
            IJobDetail job = JobBuilder.Create<MyJob>()
                                       .WithIdentity("MyJob")
                                       .Build();
            ITrigger trigger = TriggerBuilder.Create()
                                             .WithIdentity("Trigger")
                                             .StartNow()
                                             .WithSimpleSchedule(x => x
                                                .WithInterval(TimeSpan.FromMinutes(1))
                                                .RepeatForever())
                                             .Build();

            // Run it all
            scheduler.Start();
            scheduler.ScheduleJob(job, trigger);
        }
    }

    class MyJob : IJob
    {
        public void Execute(IJobExecutionContext context)
        {
            var history = context.Scheduler.Context["History"] as StringBuilder;
            history.AppendLine(context.NextFireTimeUtc.ToString());
            Console.WriteLine(context.NextFireTimeUtc);
        }
    }
}
like image 77
Ostati Avatar answered Dec 22 '22 14:12

Ostati