Pregunta

Parece que nuestra implementación del uso de Quartz - JDBCJobStore junto con Spring, Hibernate y Websphere está lanzando subprocesos no administrados.

He leído un poco y encontré un artículo técnico de IBM que indica que el uso de Quartz con Spring causará eso. Hacen la sugerencia de utilizar CommnonJ para abordar este problema.

He investigado un poco más y los únicos ejemplos que he visto hasta ahora se relacionan con el antiguo JobStore que no está en una base de datos.

Entonces, me preguntaba si alguien tiene un ejemplo de la solución para este problema.

Gracias

¿Fue útil?

Solución

Tenemos una solución de trabajo para esto (dos en realidad).

1) Modifique el código fuente de cuarzo para usar un subproceso de daemon de WorkManager para el subproceso del programador principal. Funciona, pero requiere cambiar los cuartos de galón. Sin embargo, no usamos esto porque no queríamos mantener una versión pirateada de cuarzo. (Eso me recuerda que iba a enviar esto al proyecto pero se me olvidó por completo)

2) Cree un WorkManagerThreadPool para utilizarlo como la agrupación de hilos de cuarzo. Implemente la interfaz para el ThreadPool de cuarzo, de modo que cada tarea que se desencadene dentro de cuarzo se envuelva en un objeto de trabajo común que luego se programará en el WorkManager. La clave es que el WorkManager en el WorkManagerThreadPool debe inicializarse antes de que se inicie el programador, desde un subproceso de Java EE (como la inicialización de servlet). El WorkManagerThreadPool debe crear un hilo de daemon que manejará todas las tareas programadas creando y programando los nuevos objetos de trabajo. De esta manera, el programador (en su propio hilo) pasa las tareas a un hilo gestionado (el daemon de trabajo).

No es simple, y desafortunadamente no tengo código disponible para incluir.

Otros consejos

Agregando otra respuesta al hilo, ya que finalmente encontré una solución para esto.

Mi entorno : ERA 8.5.5, Cuarzo 1.8.5, sin resorte.

El problema que tuve fue el subproceso no administrado (mencionado anteriormente) que causa una excepción de NamingException de ctx.lookup (myJndiUrl) , que en su lugar funcionaba correctamente en otros servidores de aplicaciones ( JBoss, weblogic); en realidad, Webpshere estaba disparando un " incidente " con el siguiente mensaje:

  

javax.naming.ConfigurationException: una operación JNDI en un " java: " el nombre no se puede completar porque el tiempo de ejecución del servidor no puede asociar el subproceso de la operación con ningún componente de la aplicación J2EE. Esta condición puede ocurrir cuando el cliente JNDI usa " java: " El nombre no se ejecuta en el hilo de una solicitud de aplicación del servidor. Asegúrese de que una aplicación J2EE no ejecute operaciones JNDI en " java: " nombres dentro de bloques de código estático o en hilos creados por esa aplicación J2EE. Dicho código no necesariamente se ejecuta en el subproceso de una solicitud de aplicación del servidor y, por lo tanto, no es compatible con las operaciones JNDI en " java: " nombres.

Los siguientes pasos resolvieron el problema:

1) actualizado a cuarzo 1.8.6 (sin cambios de código), solo maven pom

2) agregó la siguiente sección a classpath (en mi caso, la carpeta EAR / lib), para hacer que el nuevo WorkManagerThreadExecutor esté disponible

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

Nota: en QTZ-113 o la documentación oficial de Quartz 1.x 2.x no hay ninguna mención sobre cómo activar esta corrección.

3) agregó lo siguiente a quartz.properties (" wm / default " era el JNDI del DefaultWorkManager ya configurado en mi WAS 8.5.5, vea Recursos - > AsynchronousBeans - > WorkManagers en la consola WAS):

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

Nota: la clase correcta es org.quartz. personalizado .WorkManagerThreadExecutor para quartz-scheduler-1.8.6 (probado), o org.quartz. < strong> commonj .WorkManagerThreadExecutor desde 2.1.1 en (no probado, pero verificado dentro de tarros de quartz-commonj en los repositorios del experto)

4) movió la búsqueda JNDI en el constructor vacío del trabajo de cuarzo (gracias a m_klovre's Thread fuera del contenedor J2EE " ); es decir, el constructor estaba siendo invocado por el método de reflexión ( newInstance () ) desde el mismo contexto J2EE de mi aplicación, y tenía acceso al espacio de nombres java: global , mientras que el método execute (JobExecutionContext) todavía se estaba ejecutando en un contexto más pobre, al que le faltaban todos los EJB de mi aplicación

Espero que esto ayude.

Ps. como referencia, puede encontrar aquí un ejemplo del archivo quartz.properties que estaba usando arriba

Revisa este artículo: http://www.ibm.com/developerworks/websphere/techjournal/ 0609_alcott / 0609_alcott.html

básicamente, establezca la propiedad taskExecutor en SchedulerFactoryBean para usar un org.springframework.scheduling.commonj.WorkManager TaskExecutor que usará subprocesos administrados por contenedor.

Solo una nota: el enlace de QUARTZ-708 anterior ya no es válido. Parece que este nuevo problema (en una nueva Jira) trata el problema: http://jira.terracotta.org/jira/browse/QTZ-113 (fixVersion = 1.8.6, 2.0.2)

Puede consultar el siguiente enlace de JIRA sobre cuarzo al respecto.

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

Esto tiene la implementación requerida de WebSphereThreadPool que se puede usar con los cambios en quartz.properties como se menciona para cumplir con sus requisitos. Espero que esto ayude.

Saludos, Siva

Tendrá que usar los grupos de subprocesos gestionados de websphere. Puedes hacerlo a través de spring y commonj. CommonJ puede tener un ejecutor de tareas que creará hilos administrados. Incluso puede utilizar una referencia a un recurso de subproceso administrado jndi. Luego, puede inyectar el ejecutor de tareas comunes en Quartz SchedulerFactoryBean basado en Spring.

Consulte http://open.bekk.no/boss/spring -scheduling-in-websphere / y desplácese hasta " Quartz with CommonJ " sección para más detalles.

La propuesta de PaoloC para WAS85 y Quartz 1.8.6 también funciona en WAS80 (y Quartz 1.8.6) y no necesita Spring. (En mi configuración, Spring 2.5.5 está presente, pero no está en uso en ese contexto).

De esa manera pude anular SimpleJobFactory por mi propia variante, usando un InjectionHelper para aplicar CDI en cada trabajo recién creado. La inyección funciona tanto para @EJB (con la búsqueda JNDI de la interfaz empresarial remota EJB anotada) como para @Inject (con la búsqueda JNDI del CDI BeanManager usando un nuevo InitialContext primero, y luego usando este BM recién recuperado para buscar el propio bean CDI).

Gracias PaoloC por esa respuesta! (Espero que este texto aparezca como una "respuesta a PaoloC" y no como una respuesta al tema principal. No se encuentran formas de diferenciar entre estos).

Recientemente he encontrado este problema. Prácticamente necesitas:

  1. Implemente el grupo de subprocesos delegando el trabajo a Websphere Work Manager. (Quartz solo proporciona SimpleThreadPool que ejecuta trabajos en subprocesos no administrados). Dígale a quartz que use este grupo de subprocesos mediante la propiedad org.quartz.threadPool.class
  2. Dígale a quartz que use WorkManagerThreadExecutor (o implemente una personalizada) por org.quartz.threadExecutor.class propiedad
  3. Un poco de paciencia con los incómodos contenedores web heredados :)

Aquí está demo de github de usar Quartz con Websphere (y también Tomcat).

Espero que ayude a alguien ..

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top