title: Quartz JobStore: JobPersistenceException: Couldn't retrieve trigger: ClassNotFoundException
body: <p>I'm hoping one of you lovely people will be able to help me with this, as I've spent a number of fruitless hours already trying to make everything play nice! </p>
  
  <p>I've traced the issue down to Classloading, and been able to see that when Quartz tries to de-serialise jobDetail's from a jobStore (jobStoreCMT), the Classloader used does not contain any of my applications classes, and only the libraries defined in the EARs lib folder.</p>
  
  <p>So... I'm obviously using an application server, and in this case tried against Glassfish 3.1.1/3.1.2</p>
  
  <p>tried against Quartz 1.8.6/2.1.5
  using Spring 3.1.0.RELEASE</p>
  
  <p>Spring/Quartz config:</p>
  
  <pre><code>&lt;bean id="schedulerFactoryBean" class="org.springframework.scheduling.quartz.SchedulerFactoryBean"&gt;
      &lt;property name="dataSource" ref="dataSource" /&gt;
      &lt;property name="overwriteExistingJobs" value="true" /&gt;
  
      &lt;property name="triggers"&gt;
          &lt;list&gt;
              &lt;ref bean="notificationEmailsSimpleTrigger" /&gt;
          &lt;/list&gt;
      &lt;/property&gt;
  
      &lt;property name="quartzProperties"&gt;
          &lt;props&gt;
              &lt;prop key="org.quartz.scheduler.instanceName"&gt;QuartzScheduler&lt;/prop&gt;
              &lt;prop key="org.quartz.scheduler.instanceId"&gt;AUTO&lt;/prop&gt;
  
              &lt;prop key="org.quartz.threadPool.class"&gt;org.quartz.simpl.SimpleThreadPool&lt;/prop&gt;
              &lt;prop key="org.quartz.threadPool.threadCount"&gt;25&lt;/prop&gt;
              &lt;prop key="org.quartz.threadPool.threadPriority"&gt;5&lt;/prop&gt;
              &lt;prop key="org.quartz.jobStore.class"&gt;org.quartz.impl.jdbcjobstore.JobStoreCMT&lt;/prop&gt;
              &lt;prop key="org.quartz.jobStore.driverDelegateClass"&gt;org.quartz.impl.jdbcjobstore.StdJDBCDelegate&lt;/prop&gt;
              &lt;prop key="org.quartz.jobStore.misfireThreshold"&gt;60000&lt;/prop&gt;
              &lt;prop key="org.quartz.jobStore.tablePrefix"&gt;QRTZ_&lt;/prop&gt;
              &lt;!-- &lt;prop key="org.quartz.jobStore.isClustered"&gt;true&lt;/prop&gt; --&gt;
              &lt;!-- &lt;prop key="org.quartz.jobStore.clusterCheckinInterval"&gt;20000&lt;/prop&gt; --&gt;
  
              &lt;prop key="org.quartz.scheduler.classLoadHelper.class"&gt;org.quartz.simpl.CascadingClassLoadHelper&lt;/prop&gt;
              &lt;prop key="org.quartz.scheduler.threadsInheritContextClassLoaderOfInitializer"&gt;true&lt;/prop&gt;
              &lt;prop key="org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread"&gt;true&lt;/prop&gt;
  
              &lt;prop key="org.quartz.scheduler.skipUpdateCheck"&gt;true&lt;/prop&gt;
          &lt;/props&gt;
      &lt;/property&gt;
  &lt;/bean&gt;
  </code></pre>
  
  <p>and the corresponding trigger reference:</p>
  
  <pre><code>&lt;bean id="notificationEmailsSimpleTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerFactoryBean"&gt;
      &lt;property name="jobDetail" ref="notificationJobDetail" /&gt;
      &lt;property name="repeatInterval" value="60000" /&gt;
  &lt;/bean&gt;
  
  &lt;bean id="notificationJobDetail" class="org.springframework.scheduling.quartz.JobDetailFactoryBean"&gt;
      &lt;property name="jobClass" value="com.mcboom.social.notifications.NotificationQuartzJobBean" /&gt;
  &lt;/bean&gt;
  </code></pre>
  
  <p>So the problem I'm having is this: any combination of the below doesn't seem to effect the classloader being used.</p>
  
  <pre><code>    &lt;prop key="org.quartz.scheduler.classLoadHelper.class"&gt;org.quartz.simpl.CascadingClassLoadHelper&lt;/prop&gt;
      &lt;prop key="org.quartz.scheduler.threadsInheritContextClassLoaderOfInitializer"&gt;true&lt;/prop&gt;
      &lt;prop key="org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread"&gt;true&lt;/prop&gt;
  </code></pre>
  
  <p>Or more specifically dont help when trying to retrieve a previously persisted trigger, resulting in the following stracktrace:</p>
  
  <pre><code>INFO: ERROR - ErrorLogger.schedulerError(schedulerFactoryBean_QuartzSchedulerThread)(2358) | An error occured while scanning for the next trigger to fire.
  org.quartz.JobPersistenceException: Couldn't acquire next trigger: Couldn't retrieve trigger: com.mcboom.social.notifications.NotificationQuartzJobBean [See nested exception: org.quartz.JobPersistenceException: Couldn't retrieve trigger: com.mcboom.social.notifications.NotificationQuartzJobBean [See nested exception: java.lang.ClassNotFoundException: com.mcboom.social.notifications.NotificationQuartzJobBean]]
  at org.quartz.impl.jdbcjobstore.JobStoreSupport.acquireNextTrigger(JobStoreSupport.java:2814)
  at org.quartz.impl.jdbcjobstore.JobStoreSupport$36.execute(JobStoreSupport.java:2757)
  at org.quartz.impl.jdbcjobstore.JobStoreSupport.executeInNonManagedTXLock(JobStoreSupport.java:3788)
  at org.quartz.impl.jdbcjobstore.JobStoreSupport.acquireNextTrigger(JobStoreSupport.java:2753)
  at org.quartz.core.QuartzSchedulerThread.run(QuartzSchedulerThread.java:263)
  Caused by: org.quartz.JobPersistenceException: Couldn't retrieve trigger: com.mcboom.social.notifications.NotificationQuartzJobBean [See nested exception: java.lang.ClassNotFoundException: com.mcboom.social.notifications.NotificationQuartzJobBean]
  at org.quartz.impl.jdbcjobstore.JobStoreSupport.retrieveTrigger(JobStoreSupport.java:1596)
  at org.quartz.impl.jdbcjobstore.JobStoreSupport.retrieveTrigger(JobStoreSupport.java:1572)
  at org.quartz.impl.jdbcjobstore.JobStoreSupport.acquireNextTrigger(JobStoreSupport.java:2792)
  ... 4 more
  </code></pre>
  
  <p>I can see the <strong>org.quartz.simpl.CascadingClassLoadHelper</strong> being used on-load, and correctly selecting the right classloader. </p>
  
  <p>Problem is that when the <strong>QuartzSchedulerThread</strong> tries to retrieve a trigger it uses <strong>JobStoreSupport.retrieveTrigger()</strong>, which in turn falls-back to <strong>ObjectInputsStream.resolveClass()</strong>, and the following line of code:</p>
  
  <pre><code>Class.forName(name, false, latestUserDefinedLoader())
  </code></pre>
  
  <p>Where <strong>latestUserDefinedLoader()</strong> always returns the wrong classloader...resulting in the ClassNotFoundException and leaving me pretty flummoxed!</p>
  
  <p>I should point out that <strong>latestUserDefinedLoader()</strong> is a native method of ObjectInputsStream, and i'm using jdk 1.6 on OSX.</p>
  
  <p>Can anyone from either the Quartz/ Spring or more likely Glassfish community shed some light on this, I'm pulling my hair out at the moment.</p>
  
  <p>Thanks Steve.</p>