Unmanaged Threads Spring Quartz Websphere Hibernate

前端 未结 8 2079
囚心锁ツ
囚心锁ツ 2020-12-06 06:54

It appears that our implementation of using Quartz - JDBCJobStore along with Spring, Hibernate and Websphere is throwing unmanaged threads.

I have done some readin

相关标签:
8条回答
  • 2020-12-06 07:15

    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

    0 讨论(0)
  • 2020-12-06 07:19

    You can check the below JIRA link raised on quartz regarding this.

    http://jira.opensymphony.com/browse/QUARTZ-708

    This has the required WebSphereThreadPool implementation which can be used with the changes in quartz.properties as mentioned to meet your requirements. Hope this helps.

    Regards, Siva

    0 讨论(0)
  • 2020-12-06 07:21

    I have recently encountered this problem. Practically you need:

    1. Implement thread pool by delegating work to Websphere Work Manager. (Quartz provides only SimpleThreadPool that run jobs on unmanaged threads). Tell quartz to use this thread pool by org.quartz.threadPool.class property
    2. Tell quartz to use WorkManagerThreadExecutor (or implement custom one) by org.quartz.threadExecutor.class property
    3. A bit patience with cumbersome legacy web containers :)

    Here is github demo of using Quartz with Websphere (and also Tomcat).

    Hope it helps someone..

    0 讨论(0)
  • 2020-12-06 07:25

    You will have to use websphere's managed thread pools. You can do this via spring and commonj. CommonJ can has a task executor that will create managed threads. You can even use a reference to a jndi managed thread resource. You can then inject the commonj task executor into the Spring based Quartz SchedulerFactoryBean.

    Please see http://open.bekk.no/boss/spring-scheduling-in-websphere/ and scroll to "Quartz with CommonJ" section for more details.

    0 讨论(0)
  • 2020-12-06 07:30

    We have a working solution for this (two actually).

    1) Alter the quartz source code to use a WorkManager daemon thread for the main scheduler thread. It works, but requires changing quarts. We didn't use this though since we didn't want maintain a hacked version of quartz. (That reminds me, I was going to submit this to the project but completely forgot)

    2) Create a WorkManagerThreadPool to be used as the quartz threadpool. Implement the interface for the quartz ThreadPool, so that each task that is triggered within quartz is wrapped in a commonj Work object that will then be scheduled in the WorkManager. The key is that the WorkManager in the WorkManagerThreadPool has to be initialized before the scheduler is started, from a Java EE thread (such as servlet initialization). The WorkManagerThreadPool must then create a daemon thread which will handle all the scheduled tasks by creating and scheduling the new Work objects. This way, the scheduler (on its own thread) is passing the tasks to a managed thread (the Work daemon).

    Not simple, and unfortunately I do not have code readily available to include.

    0 讨论(0)
  • 2020-12-06 07:30

    Just a note: the above QUARTZ-708's link is not valid anymore. This new issue (in a new Jira) seems to be addressing the problem: http://jira.terracotta.org/jira/browse/QTZ-113 (fixVersion = 1.8.6, 2.0.2)

    0 讨论(0)
提交回复
热议问题