It appears that our implementation of using Quartz - JDBCJobStore along with Spring, Hibernate and Websphere is throwing unmanaged threads.
I have done some reading and found a tech article from IBM stating that the usage of Quartz with Spring will cause that. They make the suggestion of using CommnonJ to address this issue.
I have done some further research and the only examples I have seen so far all deal with the plan old JobStore that is not in a database.
So, I was wondering if anyone has an example of the solution for this issue.
Thanks
I have recently encountered this problem. Practically you need:
org.quartz.threadPool.class
propertyWorkManagerThreadExecutor
(or implement custom one) by org.quartz.threadExecutor.class
propertyHere is github demo of using Quartz with Websphere (and also Tomcat).
Hope it helps someone..
Adding another answer to the thread, since i found a solution for this, finally.
My environment: WAS 8.5.5, Quartz 1.8.5, no Spring.
The problem i had was the (above stated) unmanaged thread causing a NamingException from ctx.lookup(myJndiUrl)
, that was instead correctly working in other application servers (JBoss, Weblogic); actually, Webpshere was firing an "incident" with the following message:
javax.naming.ConfigurationException: A JNDI operation on a "java:" name cannot be completed because the server runtime is not able to associate the operation's thread with any J2EE application component. This condition can occur when the JNDI client using the "java:" name is not executed on the thread of a server application request. Make sure that a J2EE application does not execute JNDI operations on "java:" names within static code blocks or in threads created by that J2EE application. Such code does not necessarily run on the thread of a server application request and therefore is not supported by JNDI operations on "java:" names.
The following steps solved the problem:
1) upgraded to quartz 1.8.6 (no code changes), just maven pom
2) added the following dep to classpath (in my case, EAR's /lib folder), to make the new WorkManagerThreadExecutor available
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz-commonj</artifactId>
<version>1.8.6</version>
</dependency>
Note: in QTZ-113 or the official Quartz Documentation 1.x 2.x there's no mention on how to activate this fix.
3) added the following to quartz.properties ("wm/default" was the JNDI of the already configured DefaultWorkManager in my WAS 8.5.5, see Resources -> AsynchronousBeans -> WorkManagers in WAS console):
org.quartz.threadExecutor.class=org.quartz.custom.WorkManagerThreadExecutor
org.quartz.threadExecutor.workManagerName=wm/default
Note: right class is org.quartz.custom.WorkManagerThreadExecutor for quartz-scheduler-1.8.6 (tested), or org.quartz.commonj.WorkManagerThreadExecutor from 2.1.1 on (not tested, but verified within actual quartz-commonj's jars on maven's repos)
4) moved the JNDI lookup in the empty constructor of the quartz job (thanks to m_klovre's "Thread outside of the J2EE container"); that is, the constructor was being invoked by reflection (newInstance()
method) from the very same J2EE context of my application, and had access to java:global
namespace, while the execute(JobExecutionContext)
method was still running in a poorer context, which was missing all of my application's EJBs
Hope this helps.
Ps. as a reference, you can find here an example of the quartz.properties file I was using above
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With