Question

Il semble que notre implémentation de Quartz - JDBCJobStore avec Spring, Hibernate et Websphere jette des threads non gérés.

J'ai lu un article et trouvé un article technique d'IBM affirmant que l'utilisation de Quartz avec Spring causera ce problème. Ils suggèrent d’utiliser CommnonJ pour résoudre ce problème.

J'ai effectué d'autres recherches et les seuls exemples que j'ai vus jusqu'à présent concernent tous le plan ancien JobStore qui ne se trouve pas dans une base de données.

Je me demandais donc si quelqu'un avait un exemple de solution à ce problème.

Merci

Était-ce utile?

La solution

Nous avons une solution de travail pour cela (deux en fait).

1) Modifiez le code source quartz pour utiliser un thread de démon WorkManager pour le thread du planificateur principal. Cela fonctionne, mais nécessite de changer les litres. Nous ne l’avons pas utilisée car nous ne voulions pas conserver une version piratée du quartz. (Cela me rappelle que j'allais soumettre cela au projet mais que je l'avais complètement oublié)

2) Créez un WorkManagerThreadPool à utiliser comme pool de threads quartz. Implémentez l'interface pour le ThreadPool de quartz afin que chaque tâche déclenchée dans quartz soit encapsulée dans un objet Workj commun qui sera ensuite planifié dans le WorkManager. La clé est que le WorkManager dans WorkManagerThreadPool doit être initialisé avant le démarrage du planificateur, à partir d'un thread Java EE (tel que l'initialisation du servlet). WorkManagerThreadPool doit ensuite créer un thread démon qui gérera toutes les tâches planifiées en créant et en planifiant les nouveaux objets de travail. Ainsi, le planificateur (sur son propre thread) passe les tâches à un thread géré (le démon Work).

Ce n’est pas simple et, malheureusement, je n’ai pas de code disponible pour l’inclusion.

Autres conseils

Ajouter une autre réponse à la discussion, car j’ai trouvé une solution pour cela, enfin.

Mon environnement : WS 8.5.5, Quartz 1.8.5, no Spring.

Le problème que je rencontrais était le thread non géré (indiqué ci-dessus) qui provoquait une exception NamingException de ctx.lookup (myJndiUrl) , qui fonctionnait correctement dans d'autres serveurs d'applications ( JBoss, Weblogic); en fait, Webpshere tirait sur un "incident". avec le message suivant:

  

javax.naming.ConfigurationException: opération JNDI sur un " java: " nom ne peut pas être complété car le serveur d’exécution ne peut associer le thread de l’opération à aucun composant d’application J2EE. Cette situation peut se produire lorsque le client JNDI utilise le "java:". name n'est pas exécuté sur le thread d'une requête d'application serveur. Assurez-vous qu’une application J2EE n’exécute pas d’opérations JNDI sur " java: " noms dans des blocs de code statiques ou dans des threads créés par cette application J2EE. Un tel code ne s’exécute pas nécessairement sur le thread d’une requête d’application serveur et n’est donc pas pris en charge par les opérations JNDI sur "java:". noms.

Les étapes suivantes ont résolu le problème:

1) a été mis à niveau vers la version 1.8.6 de quartz (aucun changement de code), juste en pom

2) a ajouté le dep suivant à classpath (dans mon cas, le dossier EAR / lib), pour rendre le nouveau WorkManagerThreadExecutor disponible

<dependency>
  <groupId>org.quartz-scheduler</groupId>
  <artifactId>quartz-commonj</artifactId>
  <version>1.8.6</version>
</dependency>

Remarque: dans la QTZ-113 ou la documentation officielle de Quartz 1.x 2.x , il n’ya aucune mention sur la façon d’activer ce correctif.

3) a ajouté le texte suivant à quartz.properties ("wm / default" était le JNDI du gestionnaire DefaultWorkManager déjà configuré dans mon WAS 8.5.5, voir Ressources - > AsynchronousBeans - > WorkManagers dans la console WAS):

org.quartz.threadExecutor.class=org.quartz.custom.WorkManagerThreadExecutor
org.quartz.threadExecutor.workManagerName=wm/default

Remarque: la classe appropriée est org.quartz. personnalisé .WorkManagerThreadExecutor pour quartz-scheduler-1.8.6 (testé) ou org.quartz. < strong> commonj .WorkManagerThreadExecutor à partir de 2.1.1 sur (non testé, mais vérifié dans les conditions réelles les jarres de quartz-commonj sur la mise en pension de maven)

4) a déplacé la recherche JNDI dans le constructeur vide du travail quartz (grâce à Le thread de m_klovre en dehors du conteneur J2EE ); en d’autres termes, le constructeur était appelé par la méthode réflexion ( newInstance () ) du même contexte J2EE de mon application et avait accès à l’espace de noms java: global , tandis que la méthode execute (JobExecutionContext) était toujours en cours d'exécution dans un contexte plus pauvre, où manquaient tous les EJB de mon application

J'espère que cela vous aidera.

Ps. à titre de référence, vous pouvez trouver ici un exemple du fichier quartz.properties que j'utilisais ci-dessus

Voir cet article: http://www.ibm.com/developerworks/websphere/techjournal/ 0609_alcott / 0609_alcott.html

En gros, définissez la propriété taskExecutor sur SchedulerFactoryBean pour utiliser un org.springframework.scheduling.commonj.WorkManager TaskExecutor qui utilisera des threads gérés par le conteneur.

Juste une note: le lien ci-dessus du QUARTZ-708 n'est plus valide. Ce nouveau numéro (dans une nouvelle Jira) semble régler le problème: http://jira.terracotta.org/jira/browse/QTZ-113 (fixVersion = 1.8.6, 2.0.2)

Vous pouvez vérifier le lien JIRA ci-dessous créé sur quartz à cet égard.

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

Il possède l'implémentation WebSphereThreadPool requise, qui peut être utilisée avec les modifications apportées à quartz.properties, comme indiqué pour répondre à vos exigences. J'espère que cela vous aidera.

Cordialement, Siva

Vous devrez utiliser les pools de threads gérés de Websphere. Vous pouvez le faire via printemps et communj. CommonJ peut avoir un exécuteur de tâches qui créera des threads gérés. Vous pouvez même utiliser une référence à une ressource de thread gérée par jndi. Vous pouvez ensuite injecter l'exécuteur de tâche commonj dans Quartz SchedulerFactoryBean basé sur Spring.

Veuillez consulter http://open.bekk.no/boss/spring. -scheduling-in-websphere / et faites défiler jusqu'à " Quartz with CommonJ " section pour plus de détails.

La proposition de PaoloC pour WAS85 et Quartz 1.8.6 fonctionne également sur WAS80 (et Quartz 1.8.6) et n’a pas besoin de Spring. (Dans ma configuration, Spring 2.5.5 est présent mais n'est pas utilisé dans ce contexte.)

De cette façon, j'ai pu remplacer SimpleJobFactory par ma propre variante, en utilisant un InjectionHelper pour appliquer CDI à chaque travail nouvellement créé. L'injection fonctionne à la fois pour @EJB (avec recherche JNDI de l'interface métier distante EJB annotée) et @Inject (avec recherche JNDI du CDI BeanManager utilisant d'abord un nouvel InitialContext, puis l'utilisation de ce BM extrait récemment pour rechercher le bean CDI lui-même).

Merci PaoloC pour cette réponse! (J'espère que ce texte apparaîtra comme une "réponse à PaoloC" et non comme une réponse au sujet principal. Aucun moyen de les différencier.)

J'ai récemment rencontré ce problème. En pratique, vous avez besoin de:

  1. Implémentez le pool de threads en déléguant le travail à Websphere Work Manager. (Quartz fournit uniquement SimpleThreadPool qui exécute des travaux sur des threads non gérés). Indiquez à quartz d'utiliser ce pool de threads avec la propriété org.quartz.threadPool.class
  2. Indiquez à quartz d'utiliser WorkManagerThreadExecutor (ou d'en implémenter un personnalisé) par la propriété org.quartz.threadExecutor.class
  3. Un peu de patience avec les lourds conteneurs Web hérités:)

Voici une démonstration de github > d’utiliser Quartz avec Websphere (et aussi Tomcat).

J'espère que cela aidera quelqu'un ..

scroll top