Wie kann ich einen ServletContextListener veranlassen, die Java EE-Anwendung zu stoppen?

8

Ich habe einen ServletContextListener, der einige Datenbankverwaltungsfunktionen ausführt, wenn meine Java EE-Anwendung startet. Dies wird in meiner Anwendung ausgeführt, bevor JPA und andere Teile der Anwendung gestartet / geladen werden. Wenn die Datenbankwartung fehlschlägt, protokolliere ich die Fehler. Wenn die Datenbankwartung fehlschlägt, wird die Anwendung nicht ordnungsgemäß funktionieren und ich möchte die Anwendung anhalten.

Wie kann ich die Anwendung anmutig und korrekt von ServletContextListener.contextInitialized stoppen?

Die Lösung von Viven unten ist nahe, aber nicht ganz. Wenn ich eine RuntimeException werfe, bleibt Glassfish in einem inkonsistenten Zustand, in dem auf seine Admin-Konsole nicht zugegriffen werden kann, aber ein Prozess läuft und Port 3700 (IIOP?) Geöffnet bleibt, der dann einen Neustart verhindert.

    
Freiheit 11.07.2011, 22:11
quelle

2 Antworten

5

Wenn Ihr ServletContextListener eine Ausnahme auslöst, wird die Webanwendung nicht korrekt geladen, und der Anwendungsserver kann alle nachfolgenden Anfragen blockieren (und mit einem Fehler von 500 antworten).

Es verhindert nicht gerade, dass die Anwendung gestartet wird, noch stoppt sie die Anwendung, aber sie verhindert eine weitere Verwendung der App und könnte in Ihrem Fall nützlich sein.

Nach ordnungsgemäßer Überprüfung in der Spezifikation ist dieses Verhalten in der Spezifikation nicht zwingend erforderlich. Der Server kann (nicht muss ) 500 Fehler zurückgeben. Diese Lösung muss daher vorsichtig verwendet werden.

Siehe diese Antwort für ein Zitat aus der Servlet-Spezifikation.

    
Vivien Barousse 11.07.2011 22:18
quelle
4

Fangen Sie in Ihrem Listener alle Ausnahmen ab und verwenden Sie Servletkontextattribute, um Flags oder andere nützliche Informationen über den Fehler zu speichern. Sie sollten sich wahrscheinlich auch anmelden, um anzuzeigen, dass die App nicht funktioniert.

An dieser Stelle können Ihre Optionen von der Architektur Ihrer App bestimmt werden. Wenn alle Anfragen von einem einzelnen Controller / Dispatcher-Servlet bearbeitet werden, kann es sinnvoll sein, dass die Methode init die Kontextattribute überprüft und einen UnavailableException auslöst. Beachten Sie jedoch, dass die Ausnahme nur für das spezifische Servlet gilt, das sie auslöst. Dies macht den Ansatz weniger überschaubar, wenn Ihre App viele Servlets enthält oder direkten Zugriff auf andere Ressourcen ermöglicht.

Eine andere Option wäre, einen Filter zu erstellen, der jede Anfrage abfängt, die Kontextattribute prüft und dann eine Ausnahme auslöst. Andere Variationen sind sicherlich möglich.

    
kschneid 13.07.2011 16:53
quelle