Reputation: 1
We are using:
JDK 8
Spring 5.2.16.RELEASE
Quartz - 2.3.2
Wildfly 20
Apart from the web application(.war) we have also plugins (.jar) for which the classes are loaded with the following code in the web app:
Thread.currentThread().setContextClassLoader(pluginsClassLoader);
PluginsClassLoader extends URLClassLoader
We are using
org.springframework.scheduling.quartz.QuartzBean
to define our own quartz jobs both in the war in the plugins (.jar) e.g. FSSendMessagesWorker extends QuartzBean
in a @Configuration class we have
@Bean
public JobDetailFactoryBean fsPluginSendMessagesWorkerJob() {
JobDetailFactoryBean obj = new JobDetailFactoryBean();
obj.setJobClass(FSSendMessagesWorker.class);
obj.setDurability(true);
return obj;
}
@Bean
@Scope(BeanDefinition.SCOPE_PROTOTYPE)
public SimpleTriggerFactoryBean fsPluginSendMessagesWorkerTrigger()
SimpleTriggerFactoryBean obj = new SimpleTriggerFactoryBean();
obj.setJobDetail(fsPluginSendMessagesWorkerJob().getObject());
obj.setRepeatInterval("* * * 0 1");
obj.setStartDelay(20000);
return obj;
}
After upgrading to Spring 5.3.x it looks like the all classes which extends QuartzBean and present in the .jar files could not be loaded while this was possible (worked) before in Spring 5.2.x The ones present in the main app (.war) just works fain - are loaded. Apart from Spring no other library was upgraded.
021-10-05 14:03:25,055 [] [] [] [EE-ManagedExecutorService-quartzExecutorService-Thread-1] ERROR o.s.s.q.LocalDataSourceJobStore:2867 - Error retrieving job, setting trigger state to ERROR. org.quartz.JobPersistenceException: Couldn't retrieve job because a required class was not found: com.company.plugin.fs.worker.FSSendMessagesWorker from [Module "deployment.mycompany.war" from Service Module Loader] at deployment.mycompany.war//org.quartz.impl.jdbcjobstore.JobStoreSupport.retrieveJob(JobStoreSupport.java:1393) at deployment.mycompany.war//org.quartz.impl.jdbcjobstore.JobStoreSupport.acquireNextTrigger(JobStoreSupport.java:2864) at deployment.mycompany.war//org.quartz.impl.jdbcjobstore.JobStoreSupport$41.execute(JobStoreSupport.java:2805) at deployment.mycompany.war//org.quartz.impl.jdbcjobstore.JobStoreSupport$41.execute(JobStoreSupport.java:2803) at deployment.mycompany.war//org.quartz.impl.jdbcjobstore.JobStoreSupport.executeInNonManagedTXLock(JobStoreSupport.java:3864) at deployment.mycompany.war//org.quartz.impl.jdbcjobstore.JobStoreSupport.acquireNextTriggers(JobStoreSupport.java:2802) at deployment.mycompany.war//org.quartz.core.QuartzSchedulerThread.run(QuartzSchedulerThread.java:287) at [email protected]//org.jboss.as.ee.concurrent.ControlPointUtils$ControlledRunnable.run(ControlPointUtils.java:105) at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515) at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264) at org.glassfish.javax.enterprise.concurrent//org.glassfish.enterprise.concurrent.internal.ManagedFutureTask.run(ManagedFutureTask.java:117) at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) at java.base/java.lang.Thread.run(Thread.java:834) at org.glassfish.javax.enterprise.concurrent//org.glassfish.enterprise.concurrent.ManagedThreadFactoryImpl$ManagedThread.run(ManagedThreadFactoryImpl.java:227) Caused by: java.lang.ClassNotFoundException: com.company.plugin.fs.worker.FSSendMessagesWorker from [Module "deployment.mycompany.war" from Service Module Loader] at org.jboss.modules.ModuleClassLoader.findClass(ModuleClassLoader.java:255) at org.jboss.modules.ConcurrentClassLoader.performLoadClassUnchecked(ConcurrentClassLoader.java:410) at org.jboss.modules.ConcurrentClassLoader.performLoadClass(ConcurrentClassLoader.java:398) at org.jboss.modules.ConcurrentClassLoader.loadClass(ConcurrentClassLoader.java:116) at java.base/java.lang.Class.forName0(Native Method) at java.base/java.lang.Class.forName(Class.java:398) at deployment.domibus-MSH-wildfly-5.0-SNAPSHOT.war//org.springframework.util.ClassUtils.forName(ClassUtils.java:284) at deployment.domibus-MSH-wildfly-5.0-SNAPSHOT.war//org.springframework.scheduling.quartz.ResourceLoaderClassLoadHelper.loadClass(ResourceLoaderClassLoadHelper.java:81) at deployment.domibus-MSH-wildfly-5.0-SNAPSHOT.war//org.springframework.scheduling.quartz.ResourceLoaderClassLoadHelper.loadClass(ResourceLoaderClassLoadHelper.java:87) at deployment.domibus-MSH-wildfly-5.0-SNAPSHOT.war//org.quartz.impl.jdbcjobstore.StdJDBCDelegate.selectJobDetail(StdJDBCDelegate.java:852) at deployment.domibus-MSH-wildfly-5.0-SNAPSHOT.war//org.quartz.impl.jdbcjobstore.JobStoreSupport.retrieveJob(JobStoreSupport.java:1390)
Upvotes: 0
Views: 967
Reputation: 1
The quartz has the option to register class loader via the property:
org.quartz.scheduler.classLoadHelper.class
In case setting the TCCL Transaction Context ClassLoader, make sure the cron thread has the same class loader as the class loader, which loads the "classes." In WildFly new threads, get ModuleClassLoader which can have different class scope than the one set back to thread scope in the initial stage.
Try with:
org.quartz.scheduler.classLoadHelper.class = org.quartz.simpl.InitThreadContextClassLoadHelper
Or write a custom ClassHelperLoader class.
https://www.quartz-scheduler.org/api/2.0.2/org/quartz/spi/ClassLoadHelper.html
Upvotes: 0