2009-02-10 16 views
12

Ich habe ein Java-Programm/Thread, die ich in einem Application Server (GlassFish) bereitstellen möchte. Der Thread sollte als "Dienst" ausgeführt werden, der beim Start und beim Beenden des Anwendungsservers beim Schließen des Anwendungsservers gestartet wird.Threading in einem Anwendungsserver

Wie würde ich das machen? Es ist nicht wirklich eine Session Bean oder MDB. Es ist nur ein roter Faden.

+0

Neugier: Warum müssen Sie einen Thread starten? Es fühlt sich immer schlecht an, wenn man Threads in einem AppServer starten muss ... – Guillaume

+0

Der Thread soll eine Instanz von HSQL DB Server laufen lassen – systemoutprintln

Antwort

1

Erstellen Sie ein Servlet, dessen Init-Methode einen Thread startet, der das Hauptprogramm ist.

public void init() throws ServletException { 
    mailThread = new MailSendThread(); 
    mailThread.start(); 
} 

In unserer web.xml-Datei der Anwendung ein Servlet hinzufügen, die ein Last-on-startup Element enthält, wo die Zahl die Reihenfolge, in der sie beginnt.

<servlet> 
    <servlet-name>Mail Sending Servlet</servlet-name> 
    <servlet-class>MailServlet</servlet-class> 
    <load-on-startup>2</load-on-startup> 
</servlet> 
3

Dies sollten Sie auf keinem App-Server tun, es sei denn, Sie haben Zugriff auf vom App-Server bereitgestellte verwaltete Threads. Ich bin nicht vertraut mit Glassfish, aber Sie können dies in Websphere oder Weblogic mit einem gemeinsamen WorkManager tun.

Offenbar kann das gleiche in Glassfish und JBOSS über einen JCA WorkManager (den ich nicht kenne) erreicht werden.

7

Ich habe das nur mit Tomcat gemacht, aber es sollte in Glassfish funktionieren.

Erstellen Sie eine Listener-Klasse, die javax.servlet.ServletContextListener implementiert, und legen Sie sie in web.xml ab. Es wird benachrichtigt, wenn Ihre Web App gestartet und zerstört wird.

Eine einfache Listener-Klasse:

public class Listener implements javax.servlet.ServletContextListener { 

    MyThread myThread; 

    public void contextInitialized(ServletContextEvent sce) { 
     myThread = new MyThread(); 
     myThread.start(); 
    } 

    public void contextDestroyed(ServletContextEvent sce) { 
     if (myThread != null) { 
      myThread.setStop(true); 
      myThread.interrupt(); 
     } 
    } 

} 

Diese in web.xml nach der letzten 'context-param' und vor dem ersten 'Servlet' geht:

<listener> 
    <listener-class>atis.Listener</listener-class> 
</listener> 

Sie wissen nicht, ob so etwas wird empfohlen oder nicht, aber es hat in der Vergangenheit gut für mich funktioniert.

+0

Das scheint mir viel sauberer zu sein, als eine servlet.init() Methode zu entführen. Trotzdem fühle ich mich etwas unwohl beim Starten von Threads in einem AppServer. – Guillaume

+0

+1 das ist das war es zu tun. Wenn es Ihnen unangenehm ist, einen eigenen Thread zu verwalten, starten Sie Quartz im App-Server. aber tun Sie es in der SCL wie hier beschrieben. –

+0

Nizza. Funktioniert auf Glassfish 3 hier. –

0

Ich muss auch mehrere Threads erstellen, wobei jeder Thread eine Buchse zu einem anderen Remote-Prozesse geöffnet in meinem Glassfish App läuft. Server. Ich habe in die von Glassfish bereitgestellte LifecycleListener-Bean gesucht, die Sie implementieren müssen.

Ich habe einen Prototyp erstellt, um die Threading- und Socket-Arbeit in der LifecycleListener-Implementierung durchzuführen, und es half wirklich nicht bei der Verwaltung dieser Ressourcen. Um Zugriff auf den LifecycleListener zu bekommen, musste ich eine öffentliche statische Methode setzen, die die gewünschten Aktionen ausführen würde.

Ich sehe keinen Wert in LifecycleListener, weil ich exakt die gleiche Arbeit in meinem EJB ausgeführt hätte, der der Client ist, der den LifecycleListener aufruft. Weil es wirklich keine richtige Verwaltung von Thread und Socket in der Bean gibt.

Mir wurde gesagt, dass JCA der beste Weg zu gehen ist. Ich habe das nicht versucht.

0

Ich starte ein zeitgesteuertes Objekt mit dem Timer-Dienst und nur einer einzigen Ablaufzeit. Dann, in der Zeitüberschreitung, mache ich, was ich mit dem Thread machen wollte.

http://onjava.com/pub/a/onjava/2004/10/13/j2ee-timers.html

Für mich ist es seit es funktionierte verwendet J2EE-Komponenten und ist ein anderer Thread.