Domanda

Sembra che la nostra implementazione dell'utilizzo di Quartz - JDBCJobStore insieme a Spring, Hibernate e Websphere stia lanciando thread non gestiti.

Ho letto e trovato un articolo tecnico di IBM in cui si afferma che l'utilizzo di Quartz con Spring lo causerà. Suggeriscono di utilizzare CommnonJ per risolvere questo problema.

Ho fatto qualche ulteriore ricerca e gli unici esempi che ho visto finora riguardano tutti il ??piano JobStore precedente che non si trova in un database.

Quindi, mi chiedevo se qualcuno avesse un esempio della soluzione a questo problema.

Grazie

È stato utile?

Soluzione

Abbiamo una soluzione funzionante per questo (due in realtà).

1) Modifica il codice sorgente del quarzo per utilizzare un thread demone WorkManager per il thread dello scheduler principale. Funziona, ma richiede cambiare quarti. Non l'abbiamo usato però poiché non volevamo mantenere una versione hackerata di quarzo. (Questo mi ricorda che stavo per inviarlo al progetto ma l'ho completamente dimenticato)

2) Creare un WorkManagerThreadPool da utilizzare come pool di thread al quarzo. Implementare l'interfaccia per ThreadPool al quarzo, in modo che ogni attività che viene attivata in quarzo sia racchiusa in un oggetto Work comune che verrà quindi pianificato nel WorkManager. La chiave è che WorkManager in WorkManagerThreadPool deve essere inizializzato prima dell'avvio dello scheduler, da un thread Java EE (come l'inizializzazione del servlet). WorkManagerThreadPool deve quindi creare un thread demone che gestirà tutte le attività pianificate creando e pianificando i nuovi oggetti Work. In questo modo, lo scheduler (sul proprio thread) sta passando le attività a un thread gestito (il demone Work).

Non semplice, e sfortunatamente non ho codice disponibile per l'inclusione.

Altri suggerimenti

Aggiungendo un'altra risposta alla discussione, dal momento che ho trovato una soluzione per questo, finalmente.

Il mio ambiente : WAS 8.5.5, Quartz 1.8.5, no Spring.

Il problema che ho avuto è stato il thread non gestito (sopra indicato) che causava una NamingException da ctx.lookup (myJndiUrl) , che invece funzionava correttamente in altri server applicazioni ( JBoss, Weblogic); in realtà, Webpshere stava lanciando un "incidente". con il seguente messaggio:

  

javax.naming.ConfigurationException: un'operazione JNDI su un " java: " il nome non può essere completato perché il runtime del server non è in grado di associare il thread dell'operazione a nessun componente dell'applicazione J2EE. Questa condizione può verificarsi quando il client JNDI utilizza " java: " il nome non viene eseguito sul thread di una richiesta dell'applicazione server. Assicurati che un'applicazione J2EE non esegua operazioni JNDI su " java: " nomi all'interno di blocchi di codice statici o in thread creati dall'applicazione J2EE. Tale codice non viene necessariamente eseguito sul thread di una richiesta dell'applicazione server e pertanto non è supportato dalle operazioni JNDI su " java: " nomi.

I seguenti passaggi hanno risolto il problema:

1) aggiornato a quarzo 1.8.6 (nessuna modifica del codice), maven pom

2) ha aggiunto il seguente dep al classpath (nel mio caso, cartella EAR / lib), per rendere disponibile il nuovo WorkManagerThreadExecutor

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

Nota: in QTZ-113 o nella Documentazione ufficiale al quarzo 1.x 2.x non si fa menzione su come attivare questa correzione.

3) ha aggiunto quanto segue a quartz.properties (" wm / default " era il JNDI del DefaultWorkManager già configurato nel mio WAS 8.5.5, vedi Risorse - > AsynchronousBeans - > WorkManager nella console WAS):

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

Nota: la classe giusta è org.quartz. personalizzato .WorkManagerThreadExecutor per quartz-scheduler-1.8.6 (testato) o org.quartz. < strong> commonj .WorkManagerThreadExecutor da 2.1.1 in poi (non testato, ma verificato all'interno di barattoli di quarzo-commonj sui repo di maven)

4) ha spostato la ricerca JNDI nel costruttore vuoto del processo al quarzo (grazie a m_klovre's " Discussione all'esterno del contenitore J2EE " ); vale a dire, il costruttore veniva invocato da reflection (metodo newInstance () ) dallo stesso contesto J2EE della mia applicazione e aveva accesso allo spazio dei nomi java: global , mentre il metodo execute (JobExecutionContext) era ancora in esecuzione in un contesto più povero, in cui mancavano tutti i bean della mia applicazione

Spero che questo aiuti.

Ps. come riferimento, puoi trovare qui un esempio del file quartz.properties che stavo usando sopra

Controlla questo articolo: http://www.ibm.com/developerworks/websphere/techjournal/ 0609_alcott / 0609_alcott.html

fondamentalmente, imposta la proprietà taskExecutor su SchedulerFactoryBean per utilizzare un org.springframework.scheduling.commonj.WorkManager TaskExecutor che utilizzerà i thread gestiti dal contenitore.

Solo una nota: il link sopra QUARTZ-708 non è più valido. Questo nuovo numero (in una nuova Jira) sembra affrontare il problema: http://jira.terracotta.org/jira/browse/QTZ-113 (fixVersion = 1.8.6, 2.0.2)

Puoi controllare il link JIRA qui sotto sollevato su quarzo a riguardo.

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

Questo ha l'implementazione WebSphereThreadPool richiesta che può essere utilizzata con le modifiche a quartz.properties come menzionato per soddisfare le vostre esigenze. Spero che questo aiuti.

Saluti, Siva

Dovrai utilizzare i pool di thread gestiti di websphere. Puoi farlo tramite spring e commonj. CommonJ can ha un esecutore di attività che creerà thread gestiti. È anche possibile utilizzare un riferimento a una risorsa thread gestita jndi. È quindi possibile iniettare l'esecutore dell'attività commonj in Quartz SchedulerFactoryBean basato su Spring.

Si prega di consultare http://open.bekk.no/boss/spring -scheduling-in-websphere / e scorrere fino a " Quarzo con CommonJ " sezione per maggiori dettagli.

La proposta di PaoloC per WAS85 e Quartz 1.8.6 funziona anche su WAS80 (e Quartz 1.8.6) e non necessita di molla. (Nella mia installazione Spring 2.5.5 è presente, ma non in uso in quel contesto.)

In questo modo sono stato in grado di ignorare SimpleJobFactory con la mia variante, usando un InjectionHelper per applicare il CDI su ogni nuovo lavoro creato. Injection funziona sia per @EJB (con la ricerca JNDI dell'interfaccia business remota EJB con annotazioni) sia per @Inject (con la ricerca JNDI del CDI BeanManager utilizzando prima un nuovo InitialContext, quindi utilizzando questo BM appena recuperato per cercare il bean CDI stesso).

Grazie PaoloC per la risposta! (Spero che questo testo appaia come una "risposta a PaoloC" e non come una risposta all'argomento principale. Non ho trovato alcun modo per differenziarli.)

Di recente ho riscontrato questo problema. Praticamente hai bisogno di:

  1. Implementa il pool di thread delegando il lavoro a Websphere Work Manager. (Quartz fornisce solo SimpleThreadPool che esegue lavori su thread non gestiti). Di 'a quarzo di usare questo pool di thread per org.quartz.threadPool.class proprietà
  2. Di 'a quartz di usare la proprietà WorkManagerThreadExecutor (o implementa uno personalizzato) dalla proprietà org.quartz.threadExecutor.class
  3. Un po 'di pazienza con ingombranti contenitori Web legacy :)

Ecco github demo di usare Quartz con Websphere (e anche Tomcat).

Spero che aiuti qualcuno ..

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top