gpt4 book ai didi

macos - quartz JobStore : JobPersistenceException: Couldn't retrieve trigger: ClassNotFoundException

转载 作者:行者123 更新时间:2023-12-01 11:01:02 24 4
gpt4 key购买 nike

我希望你们中的一个可爱的人能够帮助我解决这个问题,因为我已经花费了许多徒劳的时间试图让一切都变得美好!

我已经将问题追溯到类加载,并且能够看到当 Quartz 尝试从 jobStore (jobStoreCMT) 反序列化 jobDetail 时,使用的类加载器不包含我的任何应用程序类,并且只包含在EARs lib 文件夹。

所以......我显然正在使用应用程序服务器,在这种情况下尝试针对 Glassfish 3.1.1/3.1.2

尝试对抗 Quartz 1.8.6/2.1.5
使用 Spring 3.1.0.RELEASE

Spring / quartz 配置:

<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 的 native 方法,我在 OSX 上使用 jdk 1.6。

Quartz/Spring 或更可能的 Glassfish 社区的任何人都可以对此有所了解吗,我现在正在拔头发。

谢谢史蒂夫。

最佳答案

如果有人对我提出的解决方案感兴趣,虽然不理想的是扩展默认值 StdJDBCDelegate ,在我的 MySQL 案例中,我可以匿名覆盖 ObjectInputStream.resolveClass()很像下面。

/**
* <p>
* This method should be overridden by any delegate subclasses that need
* special handling for BLOBs. The default implementation uses standard JDBC
* <code>java.sql.Blob</code> operations.
* </p>
*
* <p>
* This implementation overcomes the incorrect classloader being used in
* ObjectInputStream, overriding it with the current threads classloader.
* </p>
*
* @param rs
* the result set, already queued to the correct row
* @param colName
* the column name for the BLOB
* @return the deserialized Object from the ResultSet BLOB
* @throws ClassNotFoundException
* if a class found during deserialization cannot be found
* @throws IOException
* if deserialization causes an error
*/
@Override
protected Object getObjectFromBlob(ResultSet rs, String colName) throws ClassNotFoundException, IOException, SQLException {
Object obj = null;

Blob blobLocator = rs.getBlob(colName);
if (blobLocator != null && blobLocator.length() != 0) {
InputStream binaryInput = blobLocator.getBinaryStream();

if (null != binaryInput) {
if (binaryInput instanceof ByteArrayInputStream && ((ByteArrayInputStream) binaryInput).available() == 0) {
// do nothing
} else {
ObjectInputStream in = new ObjectInputStream(binaryInput) {

@Override
protected Class<?> resolveClass(ObjectStreamClass desc) throws IOException, ClassNotFoundException {
String name = desc.getName();
try {
return Class.forName(name, false, Thread.currentThread().getContextClassLoader());
} catch (ClassNotFoundException ex) {
return super.resolveClass(desc);
}
}
};

try {
obj = in.readObject();
} finally {
in.close();
}
}
}

}
return obj;
}

使用当前线程类加载器,如果不成功则回退到默认处理。

如果有人有更好的解决方案,甚至可以解释为什么会首先出现问题,我会非常想听听。

S。

关于macos - quartz JobStore : JobPersistenceException: Couldn't retrieve trigger: ClassNotFoundException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10704509/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com