Quartz Plugin

Cannot create a persistent Trigger, since all JobDetails objects are created Volatile

Details

  • Type: Bug Bug
  • Status: Closed Closed
  • Priority: Major Major
  • Resolution: Fixed
  • Affects Version/s: 0.3
  • Fix Version/s: 0.3.3
  • Component/s: None
  • Labels:
    None
  • Testcase included:
    yes

Description

In using the new 'jdbcStore' feature, I discovered that I cannot create a persistent trigger.

I am trying to persist both the jobs and triggers, since they must survive a server restart. Here I run into a problem. You make your jobs volatile and simply re-register them when the plugin loads, but Quartz will not allow me to create a non-volatile trigger if the job is volatile. So I have to somehow reregister my triggers when my application starts. I can do this in the short term, but going forward I would like to be able to register non-volatile triggers, as some trigger state can be difficult for me to reproduce.

Here is my example Trigger code:

Trigger trigger = new SimpleTrigger(generateRunOnceTriggerId(planId), PLAN_GROUP, startTime, null, 0, 0L)
trigger.setJobName("QueuePlanJob")
trigger.setJobGroup(PLAN_GROUP)
trigger.setVolatility(false)
trigger.jobDataMap.planId = planId
quartzScheduler.scheduleJob(trigger)

And here is the Job artifact that is referenced by the (plugin-generated) JobDetail object:

import org.quartz.JobDataMap

class QueuePlanJob
{
def concurrent = false
def group = "RTTE_PLAN_MGR"

// triggers are created dynamically on a per Plan basis
static triggers = {}

def planRunnerService

public void execute(def jobExecutionContext)
{
JobDataMap data = jobExecutionContext.mergedJobDataMap
log.info "Queued plan ${data.planId} for execution"
}

}

And here is the stack trace that I get when I try to register a non-volatile trigger against a volatile job:

Caused by: org.quartz.JobPersistenceException: Couldn't store trigger: It does not make sense to associate a non-volatile Trigger with a volatile Job! [See nested exception: org.quartz.JobPersistenceException: It does not make sense to associate a non-volatile Trigger with a volatile Job!]
at org.quartz.impl.jdbcjobstore.JobStoreSupport.storeTrigger(JobStoreSupport.java:1182)
at org.quartz.impl.jdbcjobstore.JobStoreSupport$5.execute(JobStoreSupport.java:1088)
at org.quartz.impl.jdbcjobstore.JobStoreSupport$39.execute(JobStoreSupport.java:3590)
at org.quartz.impl.jdbcjobstore.JobStoreCMT.executeInLock(JobStoreCMT.java:244)
at org.quartz.impl.jdbcjobstore.JobStoreSupport.executeInLock(JobStoreSupport.java:3586)
at org.quartz.impl.jdbcjobstore.JobStoreSupport.storeTrigger(JobStoreSupport.java:1084)
at org.quartz.core.QuartzScheduler.scheduleJob(QuartzScheduler.java:750)
at org.quartz.impl.StdScheduler.scheduleJob(StdScheduler.java:266)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:86)
at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:226)
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:899)
at groovy.lang.ExpandoMetaClass.invokeMethod(ExpandoMetaClass.java:946)
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:740)
at org.codehaus.groovy.runtime.InvokerHelper.invokePojoMethod(InvokerHelper.java:765)
at org.codehaus.groovy.runtime.InvokerHelper.invokeMethod(InvokerHelper.java:753)
at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.invokeMethodN(ScriptBytecodeAdapter.java:167)
at PlanRunnerService.scheduleCronPlanJob(PlanRunnerService.groovy:74)
at PlanRunnerService$$FastClassByCGLIB$$eecd189c.invoke(<generated>)
at net.sf.cglib.proxy.MethodProxy.invoke(MethodProxy.java:149)
at org.springframework.aop.framework.Cglib2AopProxy$CglibMethodInvocation.invokeJoinpoint(Cglib2AopProxy.java:700)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:149)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:106)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
at org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.intercept(Cglib2AopProxy.java:635)
... 281 more

Activity

Hide
Sergey Nebolsin added a comment -

In the latest 0.3.3-SNAPSHOT there are 'volatility' and 'durability' parameters for a Job and 'volatility' parameter for a Trigger (all are true by default). Please, test and confirm if this issue could be closed.

Sample code:

class TestJob {
    def volatility = false

    static triggers = {
        simpleTrigger timeout: 5000l, volatility: false
        simpleTrigger startDelay: 30000l, timeout: 15000l
    }

    def execute(context) {
        println context
    }
}
Show
Sergey Nebolsin added a comment - In the latest 0.3.3-SNAPSHOT there are 'volatility' and 'durability' parameters for a Job and 'volatility' parameter for a Trigger (all are true by default). Please, test and confirm if this issue could be closed. Sample code:
class TestJob {
    def volatility = false

    static triggers = {
        simpleTrigger timeout: 5000l, volatility: false
        simpleTrigger startDelay: 30000l, timeout: 15000l
    }

    def execute(context) {
        println context
    }
}
Hide
Jay Guidos added a comment -

OK I downloaded the 0.3.3.-SNAPSHOT and used the new volatility parameters as per your example.

It all works great! I suggest you can close this JIRA. Thanks for the speedy response Sergey.

Jay

Show
Jay Guidos added a comment - OK I downloaded the 0.3.3.-SNAPSHOT and used the new volatility parameters as per your example. It all works great! I suggest you can close this JIRA. Thanks for the speedy response Sergey. Jay
Hide
Sergey Nebolsin added a comment -

Fixed in rev. 41761

Show
Sergey Nebolsin added a comment - Fixed in rev. 41761

People

Vote (0)
Watch (0)

Dates

  • Created:
    Updated:
    Resolved: