Adding data to the job's context

239 views
Skip to first unread message

Luis Reyes

unread,
Oct 22, 2012, 8:38:19 PM10/22/12
to clojure...@googlegroups.com
Hi,

I'm creating a job and adding data to the job's context with the using-job-data function and no error is generated.
But when I schedule the job with the schedule function the job is not scheduled and a nullPointerException is thrown. If I eliminate the line where using-job-data is called, the job is scheduled.

What is the problem with the schedule function when data is added to the job?

(ns Dummy.Quartzite
      (:require
        [clojurewerkz.quartzite.scheduler :as qs]
        [clojurewerkz.quartzite.schedule.calendar-interval :as qse]
        [clojurewerkz.quartzite.triggers :as t]
        [clojurewerkz.quartzite.jobs :as j]
        [clojurewerkz.quartzite.conversion :as qc]
 
    )
)

defn -main    [& m]
      (qs/initialize)
      (qs/start)
    (let     [
        job    (j/build
                      (j/of-type NoOpJob)
                      (j/using-job-data  {:id "123"})
                      (j/with-identity (j/key (str "j.123"))))               
              trigger (t/build
                    (t/with-identity (t/key (str "t.123")))
                    (t/start-now)
                    (t/with-schedule (qse/schedule (qse/with-interval-in-minutes 1))))
             ]
                   
            (qs/schedule job trigger)
    )
)

Michael Klishin

unread,
Oct 23, 2012, 1:14:40 AM10/23/12
to clojure...@googlegroups.com


2012/10/23 Luis Reyes <l.ch...@gmail.com>

But when I schedule the job with the schedule function the job is not scheduled and a nullPointerException is thrown. If I eliminate the line where using-job-data is called, the job is scheduled.

What is the problem with the schedule function when data is added to the job?

Please post a stack trace. Most likely your own code tries to access job data in a way that throws
an NPE. Quartzite has special functions and tests covering job context and job data map access.

--
MK

http://github.com/michaelklishin
http://twitter.com/michaelklishin

Sven Johansson

unread,
Jan 18, 2013, 5:29:56 PM1/18/13
to clojure...@googlegroups.com
On Tuesday, October 23, 2012 7:15:20 AM UTC+2, Michael Klishin wrote:
2012/10/23 Luis Reyes <l.ch...@gmail.com>
But when I schedule the job with the schedule function the job is not scheduled and a nullPointerException is thrown. If I eliminate the line where using-job-data is called, the job is scheduled.
What is the problem with the schedule function when data is added to the job?

Please post a stack trace. Most likely your own code tries to access job data in a way that throws
an NPE. Quartzite has special functions and tests covering job context and job data map access. 
 

Was there a resolution to this? I'm getting similar mileage and I can't for the world of me figure out why.
I'm not seeing any stacktraces or NullPointerExceptions, though. 

I am using quartzite 1.0.1 an this is my code:

(ns quartzite-test.core
  (:require [clojurewerkz.quartzite.scheduler :as qs]
            [clojurewerkz.quartzite.jobs :as j]
            [clojurewerkz.quartzite.triggers :as t]
            [clojurewerkz.quartzite.conversion :as qc])
  (:use [clojurewerkz.quartzite.schedule.daily-interval :only [schedule
                                                               with-interval-in-seconds]]))

(j/defjob TestJob
  [ctx]
  (println "Here's my payload:" (qc/from-job-data ctx)))

(defn -main [] 
  (qs/initialize)
  (qs/start)
  (let [job (j/build
             (j/of-type TestJob)
             (j/using-job-data {:jack "in the box"})
             (j/with-identity (j/key "bananas")))
        trigger (t/build
                 (t/with-identity (t/key "banana-trigger"))
                 (t/start-now)
                 (t/with-schedule (schedule
                                   (with-interval-in-seconds 5))))]
    (qs/schedule job trigger)))
              
Using this code, I get only this in my console:
#inst "2013-01-18T22:24:15.000-00:00"

If I eliminate the row containing (j/using-job-data {:jack "in the box"})
the job will trigger every 5 seconds and give me this output:

#inst "2013-01-18T22:24:35.000-00:00"
Here's my payload:  {}
Here's my payload:  {}
Here's my payload:  {}
Here's my payload:  {}

And so on, and so forth...

Sticking the job data on either the job or the trigger seems to cause the job to never execute.

Any and all help appreciated!

/S

Michael Klishin

unread,
Jan 19, 2013, 5:45:10 AM1/19/13
to clojure...@googlegroups.com

2013/1/19 Sven Johansson <johanss...@gmail.com>

Sticking the job data on either the job or the trigger seems to cause the job to never execute.

Try maps with strings as keys.

Sven Johansson

unread,
Jan 19, 2013, 6:18:23 AM1/19/13
to clojure...@googlegroups.com
On Sat, Jan 19, 2013 at 11:45 AM, Michael Klishin <michael....@gmail.com> wrote:

2013/1/19 Sven Johansson <johanss...@gmail.com>
Sticking the job data on either the job or the trigger seems to cause the job to never execute.

Try maps with strings as keys.



That works perfectly! The jack is in the box! Can't believe it didn't occur to me to try that...

The one example of using-job-data in the docs on clojurequartz.info, however, does use 
keyword keys.
I just had a look to see if I could update it, but it seems that the example is pulled in from 
this gist, https://gist.github.com/e565e0520803ef7f8d3f , which I can't edit.

Thanks/S

 

Michael Klishin

unread,
Jan 19, 2013, 6:38:35 AM1/19/13
to clojure...@googlegroups.com

2013/1/19 Sven Johansson <johanss...@gmail.com>

The one example of using-job-data in the docs on clojurequartz.info, however, does use 
keyword keys.

I will fix that. Feel free to submit a PR for keywords support (we will just have to
do (name k) to map keys).

Sven Johansson

unread,
Jan 19, 2013, 12:15:02 PM1/19/13
to clojure...@googlegroups.com

2013/1/19 Sven Johansson <johanss...@gmail.com>
The one example of using-job-data in the docs on clojurequartz.info, however, does use 
keyword keys.

I will fix that. Feel free to submit a PR for keywords support (we will just have to
do (name k) to map keys).


I considered that also, but I guess that would have to be well documented. 
It's a lot better than having the job never trigger, but I would be surprised to
put in {:key "value"} and have {"key" "value"} come out the other end.

If there are no strong opinions against this, I'll give it a shot.

Also, I was unable to find a way to schedule a job/trigger to fire once a 
certain amount of time into the future using the schedule-api's in quartzite.

The Quartz/Java-version of what I'm talking about reads like this:

trigger = (SimpleTrigger) newTrigger() 
    .withIdentity("trigger5", "group1")
    .startAt(futureDate(5, IntervalUnit.MINUTE)) // use DateBuilder to create a date in the future
    .forJob(myJobKey) // identify job with its JobKey
    .build();

Unless I am missing something and there actually is a way to do this
in quartzite, I'll have look into adding that as well while I'm at it.

Cheers/S



Michael Klishin

unread,
Jan 19, 2013, 2:31:17 PM1/19/13
to clojure...@googlegroups.com

2013/1/19 Sven Johansson <johanss...@gmail.com>

If there are no strong opinions against this, I'll give it a shot.

Quartz is not aware of Clojure data types and expects a data structure that is basically
a Java map but with a cherry on top. I'm not sure how many alternatives there are.
 

Also, I was unable to find a way to schedule a job/trigger to fire once a 
certain amount of time into the future using the schedule-api's in quartzite.

Use clj-time to construct any date you want. Quartzite also has some functions
for time series calculation and other bits I wish clj-time included in quartzite.date-time.

Ludwik Grodzki Q

unread,
Apr 13, 2017, 10:37:55 AM4/13/17
to clojure-quartz
Hello.

So, I just a lost a few good hours on this, basically the map as per here:

(j/using-job-data {:jack "in the box"})

that is to be used in the payload of the job

(println "Here's my payload:" (qc/from-job-data ctx))

... as above, will basically be lost, if "in the box" was to be a map itself, it's keys would also be mangled into strings.

My workaround is to put by the proper clojure data structure into an atom so that quarts can't touch it, then I dereference it out in the job: 

(j/using-job-data {"this-has-to-a-string" (atom {:my {:proper "data"}}) })

and then in the job:
(println "Here's my payload in the atom:" (deref (get (qc/from-job-data ctx) "this-has-to-a-string")))
Reply all
Reply to author
Forward
0 new messages