# Eigene Threads im Applictionserver und JNDI



## RoNa (10. Nov 2009)

Hallo,

ich habe ein Problem mit eigenen Threads im AppServer. Wir würden gerne eigene Threads in einem AppServer benutzen, auch wenn es in der J2EE-Spec verboten ist ;-). 

Diese dürfen aber nicht auf JNDI-Resourcen zugreifen, wie Datasource. Gibt es dafür einen Trick?

Wir benutzen den Websphere. Da gibt es die Asynchronus Beans. Können die überwacht werden. Nach dem Motto: Wenn ein Thread länger als 5000 ms dauert, soll der gekillt werden.

Ansonsten würde ich gerne nur den Webcontainer benutzen.

Kann mir jemand einen Tipp geben?

Gruß,

Robert


----------



## FArt (11. Nov 2009)

Sorry, kein Tipp für mieses Design ;-)

Beschreib doch mal was du eigentlich machen möchtest, dann kriegst du vielleicht einen Tipp der dir wirklich hilft.


----------



## RoNa (11. Nov 2009)

Hi,

wir haben ein System, was periodisch gegen die Datenbank gehen muss. Später wenn der AppServer die gefundenen Objekte verarbeitet hat, muss es auf der Datenbank wieder schreiben.

Das ganze soll ohne Benutzer-Request erfolgen. Z.B. alle 20 min. Deshalb die eigenen Threads. Es gibt wohl Quartz scheduler Quartz - Quartz Overview , aber der produziert auch unmanaged Threads im AppServer.

Im Tomcat funktioniert alles OK. Aber WebSphere ist da sehr pingelig.

Hat jemand eine Idee?

Robert


----------



## maki (11. Nov 2009)

> Hat jemand eine Idee?


Kam mir so bekannt vor...
http://www.java-forum.org/allgemeines-ee/88451-jobs-websphere.html



> Im Tomcat funktioniert alles OK. Aber WebSphere ist da sehr pingelig.


Ach, nur weil man sich nicht an die Spek. hält (bzw. genau dagegen arbeitet ) macht der WebSphere gleich Probleme?
Sowas... 

Gibt einen Feature Request für Quartz: [#QUARTZ-708] Add new thread pool to use managed thread from websphere - OpenSymphony JIRA
Hier steht ein bisschen was dazu: Using Spring and Hibernate with WebSphere Application Server

Laut dem letzen Artikel sollte man Spring )) verwenden um einen Scheduler zu nutzen, damit funzt das sowohl unter Tomcat als auch unter Websphere:


> Design considerations
> ..
> *Scheduling*
> 
> Spring provides (or integrates with) a number of scheduling packages, but the only Spring scheduling package that works with threads managed by WebSphere Application Server is the CommonJ WorkManager. Other packages, such as quartz and the JDK Timer, start unmanaged threads and should be avoided.


----------



## FArt (11. Nov 2009)

EJB 3.0 Timer Services and Timer Services API in EJB 3.0

Der Quartz-Service darf natürlich nicht in EJBs verwendet werden, aber im AS schon! Als Service!


----------



## musiKk (11. Nov 2009)

FArt hat gesagt.:


> EJB 3.0 Timer Services and Timer Services API in EJB 3.0



Das wollte ich auch erst nennen, aber lässt sich damit dieses 5000ms-Limit aus dem ersten Post umsetzen?


----------



## FArt (11. Nov 2009)

> Das wollte ich auch erst nennen, aber lässt sich damit dieses 5000ms-Limit aus dem ersten Post umsetzen?


Lässt sich diese Anforderung überhaupt (sinnvoll) umsetzen?
Wie kille ich einen laufenden Thread? Gibt der auch sicher seine Ressourcen frei? Was ist z.B. mit lang laufenden DB Statements?


----------



## musiKk (11. Nov 2009)

Kein Plan. Ich sehe aber auch z. B. nicht, warum nicht einfach Quartz benutzt werden kann (das bietet ja schon einen entsprechenden [c]ServletContextListener[/c]) und warum WebLogic eine Extrawurst ist (das kriegt ja auch ein Extra-Package bei Quartz).


----------



## maki (11. Nov 2009)

> Ich sehe aber auch z. B. nicht, warum nicht einfach Quartz benutzt werden kann (das bietet ja schon einen entsprechenden ServletContextListener ) und warum WebLogic eine Extrawurst ist (das kriegt ja auch ein Extra-Package bei Quartz).


WebLogic bekommt keine Extrawurst 
Ausserdem geht es um WebSphere, aber der verhält sich genauso wie WebLogic in so einem Falle: Eigene Threads starten ist gegen die JEE Spec, der "Fehler" liegt an Quartz bzw. an dem der versucht es so zu nutzen


----------



## FArt (11. Nov 2009)

Quartz darf verwendet werden. Die Frage ist nur, in welchem Kontext. Der Themenstarter ist hier etwas ungenau. Er spricht von "eigene Threads in einem AppServer nutzen ist verboten", was ja so an sich nicht ganz stimmt.


----------



## RoNa (11. Nov 2009)

Danke für die Antworten.

Die "eigenen Threads" sollen auf Webserver Resourecen per JNDI zugreifen.

Ich weiss, Thread.stop() ist deprecated und habe auch eine Abbruchbedienung und benutze try - catch, aber sporadisch bleibt doch einer hängen. Deswegen die Kontrolle.

Gruß,

Robert


----------



## FArt (12. Nov 2009)

robertnac hat gesagt.:


> Die "eigenen Threads" sollen auf Webserver Resourecen per JNDI zugreifen.


Das sagt noch nichts über den Kontext aus, aus dem die Threads gestartet werden. Servlet? EJB? ...?



robertnac hat gesagt.:


> Ich weiss, Thread.stop() ist deprecated und habe auch eine Abbruchbedienung und benutze try - catch, aber sporadisch bleibt doch einer hängen. Deswegen die Kontrolle.


Und was bedeutet das? Was ist ein "Thread der hängen bleibt" und wie begegnest du dem?


----------



## RoNa (12. Nov 2009)

FArt hat gesagt.:


> Das sagt noch nichts über den Kontext aus, aus dem die Threads gestartet werden. Servlet? EJB? ...?



Die Threads werden gestartet im ServletContextListener#contextInitialized(). Dort wird jedenfalls die Initiierung gemacht und dann muss ein Scheduler die Threads regelmäßig starten.



FArt hat gesagt.:


> Und was bedeutet das? Was ist ein "Thread der hängen bleibt" und wie begegnest du dem?



Das sehe ich in der JConsole. Außerdem Tomcat kann dann nicht normal  beendet werden und der Websphere meldet es in der Konsole.

Gruß,

Robert


----------



## maki (12. Nov 2009)

> Das sehe ich in der JConsole. Außerdem Tomcat kann dann nicht normal beendet werden und der Websphere meldet es in der Konsole.


Wenn der Thread nicht als Deamon gekennzechnet wurde, wird Tomcat sehr lange warten bis er den Thread schliesslich "mit Gewalt" beendet.


----------



## RoNa (12. Nov 2009)

maki hat gesagt.:


> Wenn der Thread nicht als Deamon gekennzechnet wurde, wird Tomcat sehr lange warten bis er den Thread schliesslich "mit Gewalt" beendet.



Ich dachte immer Deamon-Threads laufen "unsichtbar" und man muss Threads als nicht-deamon kennzeichnen, damit sie vom übergeordneten Prozess beendet werden können.


----------



## FArt (12. Nov 2009)

> Ich dachte immer Deamon-Threads laufen "unsichtbar" und man muss Threads als nicht-deamon kennzeichnen, damit sie vom übergeordneten Prozess beendet werden können.


Das ist eine eigenwillige Übersetzung und Interpretation der Definition von Daemon-Threads, die orginal hier zu finden ist:
Thread (Java Platform SE 6)

Wenn du dich an den Lebenszyklus des Servlets bindest, kannst du auch z.B. Threads erzeugen. Ich persönlich finde es zwar nicht schön und würde das Gesamtdesign ändern, aber so weit ich weiß widerspricht das keiner Spec, weder J2EE noch Servlet.
Du musst nur darauf achten, dass alle Ressourcen weggeräumt werden, wenn das Servlet beendet wird.



> Das sehe ich in der JConsole.


Die Frage ist nicht, wie du das feststellst, sondern warum sie hängen bleiben. Wenn es lediglich um das Beenden geht, dann bist du mit den Daemon-Threads auf dem richtigen Weg. Wenn einfach so Threads hängen bleiben, solltest du dem Problem nachgehen.


----------



## RoNa (12. Nov 2009)

FArt hat gesagt.:


> Das ist eine eigenwillige Übersetzung und Interpretation der Definition von Daemon-Threads, die orginal hier zu finden ist:
> Thread (Java Platform SE 6)
> 
> Wenn du dich an den Lebenszyklus des Servlets bindest, kannst du auch z.B. Threads erzeugen. Ich persönlich finde es zwar nicht schön und würde das Gesamtdesign ändern, aber so weit ich weiß widerspricht das keiner Spec, weder J2EE noch Servlet.
> ...



Du hast vollkommen Recht. Ich kann's aber den eigentlichen Grund nicht finden, warum manche Threads sich nicht selbs terminiren. Ich probier' aber morgen die Deamon-Threads.

Ich würde gerne ein anderes Dasign des Systems planen. Aber irgendwie lande ich immer bei eigenen Threads ;-(
Wenn jemand eine Idee hat, nur her damit. Ich bin für jede Idee sehr dankbar.

Ich brauche eine Möglichkeit, dass eine Web-Anwendung regelmäßig in der Datenbank nachguckt, ob es zu dieser Zeit aktuelle Aufträge gibt, die verarbeitet werden müssen.

Ich würde gerne eine "normale" Thred-Kommunikation realisieren. Die Threads müssten dann die JNDI-Resource injiziert werden.

Weiß jemand, wie soetwas gehen könnte?

Gruß,

Robert


----------



## FArt (13. Nov 2009)

> Ich brauche eine Möglichkeit, dass eine Web-Anwendung regelmäßig in der Datenbank nachguckt, ob es zu dieser Zeit aktuelle Aufträge gibt, die verarbeitet werden müssen.


Wieso eine Webanwendung? Eine Webanwendung wartet auf Request eines Clients.

Vermutlich hast du in deinem ersten Posting schon die Lösung selber präsentiert: asynchrone Beans (kenne ich so nicht, hört sich aber gut an). Ich kenne den EJB3 TimerService (s.o.), der genau das macht, was du möchtest. Ich nehme an, ein so teurer Appserver erfüllt den EJB3 Standard und kann damit umgehen.

Zu den hängenden Threads: du kannst noch so viel mit Technik um dich schmeißen: die Logik (oder Programmierung) enthält Fehler, die du analysieren und lösen musst. Wenn der Appserver während der Verarbeitung von solchen Jobs beendet werden soll, dann macht der alles richtig, keine Angst. Kümmer dich um die Bugs und gehe den Weg, den du eh schon gehen wolltest.


----------



## faulelotte (16. Nov 2009)

Ich hoffe mal das das nicht ganz am Thema vorbei geht, 
aber warum schreibt die Applikation die periodisch die Informationen liefert nicht zb. in eine JMS Queue
und deine Logik die das dann verarbeitet wird via MDB gestartet?
Damit würdest du dir nämlich das ganze umständliche Gebastel sparen, um das mit dem Polling zu lösen.


----------



## FArt (16. Nov 2009)

faulelotte hat gesagt.:


> Ich hoffe mal das das nicht ganz am Thema vorbei geht,
> aber warum schreibt die Applikation die periodisch die Informationen liefert nicht zb. in eine JMS Queue
> und deine Logik die das dann verarbeitet wird via MDB gestartet?
> Damit würdest du dir nämlich das ganze umständliche Gebastel sparen, um das mit dem Polling zu lösen.



Prinzipiell ein möglicher Weg. Es fehlt aber eben noch an der "Applikation, die periodisch die Informationen liefert" bzw. (wenn ich das richtig verstanden habe) eigentlich nur triggert. Ob JMS dann noch nötig oder sinnvoll wäre (oder gleich vom Timer die Arbeit übernommen werden kann) liegt an weiteren Anforderungen.


----------



## RoNa (17. Nov 2009)

Die Lösung mit JMS Queue werde ich werde ich nun umsetzten. Wahrscheinlich nutze ich dann ActiveMQ Apache ActiveMQ -- Index . Die Verarbeitungslogik wird in einer message driven bean  stecken. Es gibt keine unmanaged threads mehr ;-)

So ist der Plan. Ob's gelingt und das System unter Last korrekt arbeitet wird sich zeigen.

Gruß,

Robert


----------

