私はすでにすべてをうまくプレイさせるために無駄な時間を費やしてきたので、あなたの素敵な人々の一人が私を助けてくれることを願っています!
問題を Classloading まで追跡したところ、Quartz が jobStore (jobStoreCMT) から jobDetail をデシリアライズしようとすると、使用される Classloader にはアプリケーション クラスが含まれておらず、 EARs lib フォルダー。
だから...私は明らかにアプリケーションサーバーを使用しています。この場合、Glassfish 3.1.1/3.1.2に対して試しました
Spring 3.1.0.RELEASEを使用してQuartz 1.8.6/2.1.5に対して試みました
スプリング/クォーツ構成:
<bean id="schedulerFactoryBean" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="overwriteExistingJobs" value="true" />
<property name="triggers">
<list>
<ref bean="notificationEmailsSimpleTrigger" />
</list>
</property>
<property name="quartzProperties">
<props>
<prop key="org.quartz.scheduler.instanceName">QuartzScheduler</prop>
<prop key="org.quartz.scheduler.instanceId">AUTO</prop>
<prop key="org.quartz.threadPool.class">org.quartz.simpl.SimpleThreadPool</prop>
<prop key="org.quartz.threadPool.threadCount">25</prop>
<prop key="org.quartz.threadPool.threadPriority">5</prop>
<prop key="org.quartz.jobStore.class">org.quartz.impl.jdbcjobstore.JobStoreCMT</prop>
<prop key="org.quartz.jobStore.driverDelegateClass">org.quartz.impl.jdbcjobstore.StdJDBCDelegate</prop>
<prop key="org.quartz.jobStore.misfireThreshold">60000</prop>
<prop key="org.quartz.jobStore.tablePrefix">QRTZ_</prop>
<!-- <prop key="org.quartz.jobStore.isClustered">true</prop> -->
<!-- <prop key="org.quartz.jobStore.clusterCheckinInterval">20000</prop> -->
<prop key="org.quartz.scheduler.classLoadHelper.class">org.quartz.simpl.CascadingClassLoadHelper</prop>
<prop key="org.quartz.scheduler.threadsInheritContextClassLoaderOfInitializer">true</prop>
<prop key="org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread">true</prop>
<prop key="org.quartz.scheduler.skipUpdateCheck">true</prop>
</props>
</property>
</bean>
および対応するトリガー参照:
<bean id="notificationEmailsSimpleTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerFactoryBean">
<property name="jobDetail" ref="notificationJobDetail" />
<property name="repeatInterval" value="60000" />
</bean>
<bean id="notificationJobDetail" class="org.springframework.scheduling.quartz.JobDetailFactoryBean">
<property name="jobClass" value="com.mcboom.social.notifications.NotificationQuartzJobBean" />
</bean>
したがって、私が抱えている問題は次のとおりです。以下の組み合わせは、使用されているクラスローダーに影響を与えないようです。
<prop key="org.quartz.scheduler.classLoadHelper.class">org.quartz.simpl.CascadingClassLoadHelper</prop>
<prop key="org.quartz.scheduler.threadsInheritContextClassLoaderOfInitializer">true</prop>
<prop key="org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread">true</prop>
または、より具体的には、以前に永続化されたトリガーを取得しようとしたときに役に立たず、次の stracktrace が発生します。
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
org.quartz.simpl.CascadingClassLoadHelperがロード時に使用され、適切なクラスローダーが正しく選択されていることがわかります。
問題は、QuartzSchedulerThread がトリガーを取得しようとするときに、JobStoreSupport.retrieveTrigger ( )を使用し、これがObjectInputsStream.resolveClass()にフォールバックし、次のコード行が使用されることです。
Class.forName(name, false, latestUserDefinedLoader())
latestUserDefinedLoader ()は常に間違ったクラスローダーを返します... ClassNotFoundException が発生し、私はかなり困惑しています!
latestUserDefinedLoader()は ObjectInputsStream のネイティブ メソッドであり、OSX で jdk 1.6 を使用していることを指摘しておく必要があります。
Quartz/Spring または Glassfish コミュニティの誰かがこれに光を当てることができますか?
ありがとうスティーブ。