Methode 2 - WrapperStartStopApp-Integration (Linux / UNIX)

Übersicht

Methode 2 wird eingesetzt, um die WrapperStartStopApp Helper-Klasse zu nutzen. Diese Methode liefert eine Möglichkeit für die Integration mit Anwendungen, wie z. B. mit Tomcat, die durch Nutzen einer Klasse gestartet und durch Nutzen einer anderen Klasse beendet werden.

Diese Art von Anwendung öffnet beim Starten ein Server-Socket, dessen Aufgabe es ist, auf eine Verbindung zu warten, die ein Herunterfahren auslöst. Das Herunterfahren oder die "stop"-Klasse löst, wenn gestartet, das Herunterfahren durch das Verbinden mit der Anwendung aus. Der Wrapper arbeitet mit dieser Art von Anwendung, indem er diese, wie in Methode 1, durch Nutzen der "start"-Klasse startet und dann die Main-Methode der "stop"-Klasse aufruft, wenn es Zeit ist, die Anwendung herunterzufahren.

Beim Integrieren mit Methode 2 (WrapperStartStopApp Helper-Klasse) ersetzt die WrapperStartStopApp-Klasse die Main-Klasse der Anwendung. Dies gibt der WrapperStartStopApp-Klasse eine Chance, den WrapperManager sofort zu initialisieren und die JVM mit dem Wrapper zu integrieren. Die WrapperStartStopApp-Klasse verwaltet dann die komplette Interaktion mit dem Wrapper sowie auch den Lebenszyklus der Anwendung. Wenn der Wrapper via WrapperManager eine Startnachricht an die JVM sendet, wird die Main-Methode der "start"-Klasse der Anwendung aufgerufen. Analog wird die Main-Methode der "stop"-Klasse der Anwendung aufgerufen, wenn der Wrapper eine Stop-Nachricht an die JVM sendet.

Wenn die WrapperStartStopApp-Helper-Klasse gestartet wird, muss sie über die Klassennamen von sowohl der "start"- wie auch der "stop"-Klasse informiert werden, ebenso wie über jegliche Parameter, die den Main-Methoden jeder Klasse übergeben werden müssen. Dies führt dazu, dass die Parameterliste etwas komplizierter ist, als die der Methode 1 (WrapperSimpleApp)-Helper-Klasse.

Der erste Parameter, der der WrapperStartStopApp- Klasse übergeben wird, ist der vollständige Klassennamen der "start"-Klasse. Dem folgt eine Anzahl von Parametern für die Main-Methode der "start"-Klasse, die darauf folgt. Nach den Parametern der "start"-Klasse, folgt der vollständige Name der "stop"- Klasse. Dem folgt ein TRUE/FALSE-Flag, das der WrapperStartStopApp-Klasse mitteilt, ob sie auf die Beendigung aller Nicht-Daemon-Threads warten soll, bis diese sich selbst beendet. Dem Flag folgen dann die Paramteranzahl und die Paramter der "stop"- Klasse. Lassen Sie sich nicht davon aus der Ruhe bringen, wenn dies aktuell etwas verwirrend klingt. Weiter unten finden Sie ein detailliertes Beispiel.

Detaillierte Anweisungen

Dieser Abschnitt führt Sie durch eine detaillierte Anleitung dafür, wie Tomcat innerhalb des Wrappers ausgeführt werden kann. Die meisten anderen Anwendungen können durch dieselben Schritte integriert werden.

Tomcat installieren

Dieses Tutorial startet mit einer Neuinstallation von Tomcat. Wir nutzen die Version Tomcat 9.0.0.M13, daher kann es sein, dass die Schritte bei sich leicht unterscheiden, jenachdem, welche Version Sie installieren. Tomcat wurde in dem /usr/lib-Verzeichnis installiert, so dass das Home-Verzeichnis von Tomcat /usr/lib/apache-tomcat-9.0.0.M13 lautet.

Wrapper-Dateien installieren

Es gibt vier Verzeichnisse, die konfiguriert werden müssen, damit der Wrapper verwendet werden kann.

NOTE

Bitte stellen Sie sicher, dass Sie den passenden Wrapper und die passenden libwrapper.so-Dateien benutzen, die für die auszuführende Plattform erstellt wurden. Das mag offensichtlich erscheinen, aber die Linux-Version des Wrappers wird zum Beispiel auf Solaris nicht funktionieren.

bin-Verzeichnis

Der Wrapper wird mit einem Shell-Skript ausgeliefert (sh), welches genutzt werden kann, um zuverlässig jede Java-Anwendung starten und beenden zu können, die vom Java Service Wrapper gesteuert wird.

Kopieren Sie bitte zunächst die folgende Datei in das Tomcat bin-Verzeichnis (in älteren Wrapper-Versionen hieß diese Datei 'sh.script.in'):

{WRAPPER_HOME}/bin/wrapper
{WRAPPER_HOME}/src/bin/App.sh.in

Benennen Sie die Skript-Datei um, so dass sie den Namen der Anwendung wiederspiegelt.

{TOMCAT_HOME}/bin/tomcat

Öffnen Sie nun das Skript in einem Editorprogramm. Wir müssen lange und kurze Namen festlegen, um richtig wiederzugeben, dass das Skript genutzt wird, um Tomcat zu starten. Sie werden die zwei Variablen sofort hinter dem Skriptheader sehen. APP_NAME und APP_LONG_NAME. Vorgeschlagene Werte für diese Variablen werden unten angezeigt.

APP_NAME="tomcat"
APP_LONG_NAME="Tomcat Application Server"

Das Skript sollte keine zusätzliche Abänderung erfordern. Jedoch geht es davon aus, dass sich die wrapper.conf-Datei innerhalb eines conf-Verzeichnis befindet (eine Ebene höher, ../conf/wrapper.conf). Wenn Sie die wrapper.conf-Datei woanders ablegen möchten, ist es erforderlich, dass die WRAPPER_CONF-Variable im Skript entsprechend angepasst wird.

NOTE

Wichtig! Bevor Sie fortfahren, stellen Sie bitte sicher, dass für alle Dateien, die in das bin- Verzeichnis kopiert wurden, das ausführbare Bit gesetzt wurde.

lib-Verzeichnis

Kopieren Sie die folgenden beiden Dateien in das lib-Verzeichnis von Tomcat:

{WRAPPER_HOME}/lib/libwrapper.so
{WRAPPER_HOME}/lib/wrapper.jar

Die libwrapper.so-Datei ist eine native Bibliotheksdatei, die von dem Teil des Wrappers benötigt wird, der innerhalb der JVM läuft. Die wrapper.jar-Datei beinhaltet alle Wrapper-Klassen.

NOTE

Beachten Sie bitte, dass die native Bibliothek auf ein paar Plattformen geringfügig unterschiedlichen Namensgebungsregeln folgt. Mögliche Namen beinhalten: libwrapper.a, libwrapper.sl, libwrapper.so, und libwrapper.jnilib. In jedem Fall sollte die Datei kopiert werden, ohne dass die Dateiendung sich ändert.

conf-Verzeichnis

Der Wrapper benötigt für jede Anwendung eine Konfigurationsdatei "wrapper.conf". Der Standard-Ablageort für diese Datei befindet sich in einem conf-Verzeichnis im Home-Verzeichnis der Anwendung. Bitte kopieren Sie die folgende Vorlagendatei wrapper.conf.in in das conf-Verzeichnis von Tomcat.

{WRAPPER_HOME}/src/conf/wrapper.conf.in

Benennen Sie die Datei wie folgt um. Stellen Sie dabei sicher die Endung .in zu entfernen, so dass die Datei wrapper.conf heißt.

Sie sollten nun Folgendes haben:

{TOMCAT_HOME}/conf/wrapper.conf

Wenn Sie die Konfigurationsdatei wrapper.conf in ein anderes Verzeichnis verschieben möchten, können Sie dies tun. Sie müssen die Skript-Dateien, die in das oben genannte bin-Verzeichnis kopiert wurden, ändern, damit der neue Speicherort richtig wiedergegeben wird.

logs-Verzeichnis

Die Standard-Konfigurationsdatei wrapper.conf wird eine wrapper.log-Datei in ein logs-Verzeichnis unterhalb des Home-Verzeichnisses der Anwendung ablegen. Tomcat hat dieses Verzeichnis bereits, es kann also einfach weitergehen.

{TOMCAT_HOME}/logs

Wenn Sie die wrapper.log-Datei an einem anderen Ort ablegen möchten, müssen Sie die wrapper.conf-Datei und die Eigenschaft wrapper.logfile abändern, um den neuen Ort richtig widerzuspiegeln.

Festlegen der Java-Befehlszeile der Anwendung

Bevor der Wrapper dafür konfiguriert werden kann, eine Anwendung zu starten, müssen Sie den kompletten Java-Befehl kennen, der normalerweise benutzt wird.

Die meisten Anwendungen verwenden Skripte, um die tatsächliche Befehlszeile zu erstellen. Diese Skripte neigen dazu, recht unhandlich zu werden, daher ist die Möglichkeit, nicht mit ihnen zu arbeiten, einer der Vorteile der Verwendung des Wrappers.

Tomcat wird standardmäßig durch Nutzung eines Skripts gestartet, das startup.sh heißt und durch Nutzung des Skriptes shutdown.sh beendet. Es wird gestartet, indem man zuerst das aktuelle Verzeichnis auf das bin-Verzeichnis ändert und es dann von dort ausführt. Wenn Sie startup.sh in einem Editor öffnen, werden Sie nach kurzem Prüfen feststellen, dass Java tatsächlich nicht von diesem Skript aus gestartet wird. Stattdessen wird ein anderes Skript, catalina.sh, aufgerufen. Tomcat-Skripte sind sehr fortschrittlich und erlauben es dem Nutzer viele Konfigurationen von der Befehlszeile aus vorzunehmen. Die Befehlszeile, die wir mit dem Wrapper nutzen, ist tatsächlich ein Snapshot von solch einer Konfiguration. Dieses Beispiel nimmt an, dass keine Parameter während des Ablaufs der Skripte übergeben werden, weder an das Start- noch an das Beenden-Skript.

Wenn Sie catalina.sh in einem Editor öffnen und ans Dateiende herunterscrollen, werden Sie einen Abschnitt sehen, der dem "start"-Befehl entspricht. Es gibt zwei Optionen zum Starten der JVM - mit oder ohne Sicherheitsmanager. Der Einfachheit halber werden wir die Version ohne einen Sicherheitsmanager nutzen. Die Zeilen, in die wir interessiert sind, sehen wie folgt aus:

eval $_NOHUP "\"$_RUNJAVA\"" "\"$LOGGING_CONFIG\"" $LOGGING_MANAGER $JAVA_OPTS $CATALINA_OPTS \
  -classpath "\"$CLASSPATH\"" \
  -Dcatalina.base="\"$CATALINA_BASE\"" \
  -Dcatalina.home="\"$CATALINA_HOME\"" \
  -Djava.io.tmpdir="\"$CATALINA_TMPDIR\"" \
  org.apache.catalina.startup.Bootstrap "$@" start \
  >> "$CATALINA_OUT" 2>&1 "&"

Die Mehrheit des Skripts hat die Aufgabe systemspezifische Informationen zu sammeln und diese Informationen in den Umgebungsvariablen zu speichern. Die oben gezeigte Zeile expandiert dann die gesamten gesammelten Informationen in den finalen Java-Befehl, der die Anwendung startet.

Wir hoffen, dass Sie beim Betrachten des Quellcodes des Skripts dessen Komplexität erkennen und wieso wir Ihnen abnehmen möchten, solche komplexen Skripte vollständig selbst zu schreiben.

Um den Wrapper zu konfigurieren, benötigen Sie schlussendlich nur die letzte erweiterte Befehlszeile. Anstatt das gesamte Skript zu lesen und zu versuchen, es zu verstehen, werden wir einen einfachen Trick nutzen, um die letzte Befehlszeile in der Konsole anzuzeigen. Bitte editieren Sie das Skript catalina.sh, indem Sie es wie folgt ändern:

#eval $_NOHUP "\"$_RUNJAVA\"" "\"$LOGGING_CONFIG\"" $LOGGING_MANAGER $JAVA_OPTS $CATALINA_OPTS \
  #-classpath "\"$CLASSPATH\"" \
  #-Dcatalina.base="\"$CATALINA_BASE\"" \
  #-Dcatalina.home="\"$CATALINA_HOME\"" \
  #-Djava.io.tmpdir="\"$CATALINA_TMPDIR\"" \
  #org.apache.catalina.startup.Bootstrap "$@" start \
  #>> "$CATALINA_OUT" 2>&1 "&"
echo "\"$_RUNJAVA\"" "\"$LOGGING_CONFIG\"" $LOGGING_MANAGER $JAVA_OPTS $CATALINA_OPTS \
  -classpath "\"$CLASSPATH\"" \
  -Dcatalina.base="\"$CATALINA_BASE\"" \
  -Dcatalina.home="\"$CATALINA_HOME\"" \
  -Djava.io.tmpdir="\"$CATALINA_TMPDIR\"" \
  org.apache.catalina.startup.Bootstrap "$@" start"

Wenn Sie jetzt das Skript nun noch einmal ausführen, dann werden Sie etwas wie das Folgende in der Konsole sehen (Ihre Ausgabe wird komplett in einer Zeile sein):

/opt/jdk1.8.0_45/bin/java
  "-Djava.util.logging.config.file=/usr/lib/apache-tomcat-9.0.0.M13/conf/logging.properties" 
  -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager
  -Djdk.tls.ephemeralDHKeySize=2048 
  -Djava.protocol.handler.pkgs=org.apache.catalina.webresources 
  -classpath "/usr/lib/apache-tomcat-9.0.0.M13/bin/bootstrap.jar:/usr/lib/apache-tomcat-9.0.0.M13/bin/tomcat-juli.jar" 
  -Dcatalina.base="/usr/lib/apache-tomcat-9.0.0.M13" 
  -Dcatalina.home="/usr/lib/apache-tomcat-9.0.0.M13" 
  -Djava.io.tmpdir="/usr/lib/apache-tomcat-9.0.0.M13/temp" 
  org.apache.catalina.startup.Bootstrap start

Wir müssen nun denselben Vorgang für den Stop-Befehl wiederholen. Scrollen Sie in dem Editor hinunter, um den "stop"-Befehl zu finden:

exec "$_RUNJAVA" $JAVA_OPTS \
  -classpath "$CLASSPATH" \
  -Dcatalina.base="$CATALINA_BASE" \
  -Dcatalina.home="$CATALINA_HOME" \
  -Djava.io.tmpdir="$CATALINA_TMPDIR" \
  org.apache.catalina.startup.Bootstrap "$@" stop

Bitte ändern Sie diesen Abschnitt noch einmal wie folgt:

#exec "$_RUNJAVA" $JAVA_OPTS \
  #  -classpath "$CLASSPATH" \
  #  -Dcatalina.base="$CATALINA_BASE" \
  #  -Dcatalina.home="$CATALINA_HOME" \
  #  -Djava.io.tmpdir="$CATALINA_TMPDIR" \
  #  org.apache.catalina.startup.Bootstrap "$@" stop
echo "exec $_RUNJAVA $JAVA_OPTS" \
    "-classpath $CLASSPATH" \
    "-Dcatalina.base=$CATALINA_BASE" \
    "-Dcatalina.home=$CATALINA_HOME" \
    "-Djava.io.tmpdir=$CATALINA_TMPDIR" \
    "org.apache.catalina.startup.Bootstrap $@ stop"

Wenn Sie jetzt noch einmal das Skript catalina.sh stop ausführen, werden Sie etwas wie das Folgende in der Konsole sehen (Ihre Ausgabe wird komplett in einer Zeile sein):

exec /opt/jdk1.8.0_45/bin/java
  -Djdk.tls.ephemeralDHKeySize=2048 
  -Djava.protocol.handler.pkgs=org.apache.catalina.webresources 
  -classpath "/usr/lib/apache-tomcat-9.0.0.M13/bin/bootstrap.jar:/usr/lib/apache-tomcat-9.0.0.M13/bin/tomcat-juli.jar" 
  -Dcatalina.base="/usr/lib/apache-tomcat-9.0.0.M13" 
  -Dcatalina.home="/usr/lib/apache-tomcat-9.0.0.M13"
  -Djava.io.tmpdir="/usr/lib/apache-tomcat-9.0.0.M13/temp"
  org.apache.catalina.startup.Bootstrap stop

Anders als die exec am Anfang der Herunterfahren-Zeile und die weitergeleitete Ausgabe der Startzeile, sind die beiden Befehle fast identisch. Der einzige Unterschied ist der Parameter, der am Ende an die Main-Klasse weitergegeben wird. Der exec-Teil des Herunterfahren-Befehls und die Umleitung zum Aufzeichnen der Konsolenausgabe werden nicht benötigt, wenn der Wrapper verwendet wird, daher werden diese Befehlsteile im restlichen Beispiel ignoriert.

Der Wrapper kann auch mit Elementen der Java-Befehlszeile umgehen, die er aufbaut, die in Anführungszeichen stehen. Es ist also nicht notwendig, diese in die unten angegebene Konfigurationsdatei wrapper.conf zu übertragen.

Ändern der "wrapper.conf"-Datei

Um die obengenannte Java-Befehlszeile mit dem Wrapper nutzen zu können, müssen wir die Komponenten der Befehlszeile in eine Konfigurationsdatei aufteilen. Öffnen Sie hierfür die wrapper.conf-Datei in einem Editor und nehmen Sie die unten stehenden Änderungen vor.

NOTE

Wo unten Eigenschaften genannt werden, werden Links zu ihren Beschreibungen bereitgestellt. Nehmen Sie sich bitte die Zeit, die Beschreibungen von jeglichen Eigenschaften anzuschauen, die verändert wurden. In vielen Fällen gibt es weitere Beschreibungen bezüglich ihres Einsatzes, die hier nicht aufgeführt werden.

Java-Programmdatei

Zuerst wird die Java-Programmdatei extrahiert und der Verzeichnispfad der wrapper.java.command- Eigenschaft zugewiesen:

wrapper.java.command=/opt/jdk1.8.0_45/bin/java

Java-Argumente

Die meisten Anwendungen liefern der Java-Programmdatei eine Reihe von Parametern, wenn diese gestartet wird. Der Wrapper liefert besondere Konfigurationseigenschaften für Dinge wie Speicher sowie Klassen- und Verzeichnis-Pfade. Diese werden weiter unten behandelt. Jedoch werden alle anderen Einstellungen durch den Einsatz der wrapper.java.additional.<n>- Folge an Eigenschaften konfiguriert.

Die Tomcat-Befehlszeile hat mehrere solcher Eigenschaften:

wrapper.java.additional.1=-Dcatalina.base=/usr/lib/apache-tomcat-9.0.0.M13
wrapper.java.additional.2=-Dcatalina.home=/usr/lib/apache-tomcat-9.0.0.M13
wrapper.java.additional.3=-Djava.io.tmpdir=/usr/lib/apache-tomcat-9.0.0.M13/temp
wrapper.java.additional.4=-Djdk.tls.ephemeralDHKeySize=2048
wrapper.java.additional.5=-Djava.protocol.handler.pkgs=org.apache.catalina.webresources
# Following properties are optional:
wrapper.java.additional.6=-Djava.util.logging.config.file=/usr/lib/apache-tomcat-9.0.0.M13/conf/logging.properties
wrapper.java.additional.7=-Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager

wrapper.jar

Der Wrapper erstellt die Anforderung, dass die wrapper.jar spezifiziert wird:

wrapper.jarfile=/usr/lib/apache-tomcat-9.0.0.M13/lib/wrapper.jar

WARNING

The wrapper.jarfile property was introduced in version 3.5.55. When using earlier Wrapper versions, it is necessary to include wrapper.jar in the classpath:

wrapper.java.classpath.1=D:\apache-tomcat-9.0.0.M13\lib\wrapper.jar

Then, the indices of next classpath elements must be adjusted so that the wrapper.java.classpath.1 property is not repeated.

Classpath

Als Nächstes kommt der Classpath, der unter Einsatz der wrapper.java.classpath.<n>- Eigenschaft konfiguriert wird. Der Wrapper erfordert, dass der Classpath in seine individuellen Teile aufgeteilt wird.

wrapper.java.classpath.1=/usr/lib/apache-tomcat-9.0.0.M13/bin/bootstrap.jar
wrapper.java.classpath.2=/usr/lib/apache-tomcat-9.0.0.M13/bin/tomcat-juli.jar

Main-Klasse

Die nächste Befehlskomponente, die genutzt wird, um Tomcat zu starten, ist die Main-Klasse org.apache.catalina.startup.Bootstrap. Die von Java beim Starten ausgeführte Main-Klasse wird durch Nutzung der wrapper.java.mainclass-Eigenschaft spezifiziert. Da wir, wie oben erwähnt, die WrapperStartStopApp- Helper-Klasse verwenden, um Tomcat zu starten und zu beenden, werden wir den vollständigen Namen dieser Klasse als Main-Klasse spezifizieren. Die Tomcat-Main-Klassen sind dann wie die unten genannten Anwendungsparameter spezifiziert.

wrapper.java.mainclass=org.tanukisoftware.wrapper.WrapperStartStopApp

Anwendungsparameter

Die vollständigen Informationen zur Konfiguration dieser Eigenschaften finden Sie unter: wrapper.app.parameter.<n> Anwendungsparameter erscheinen in der Java-Befehlszeile direkt hinter der Main-Klasse.

Wenn wir die WrapperStartStopApp-Helper-Klasse benutzen, müssen viele Informationen bereitgestellt werden, sowohl über die "start"- als auch die "stop"-Klasse. Diese Informationen beinhalten den vollständigen Namen, die Parameterliste, die den Main-Methoden übergeben werden und ein Flag, welches der Helper-Klasse mitteilt, ob sie warten soll, bis alle Non-Daemon-Threads beendet sind, bevor sie die JVM veranlasst, sich zu beenden.

Wir erklären im Folgenden, wie diese Information programmiertechnisch umgesetzt wird. Wir beginnen mit dem Anzeigen der Eigenschaftswerte für die Tomcat-Anwendung. Oben wurden bereits mehrere Kommentare darüber hinzugefügt, was Sie normalerweise in der wrapper.conf-Datei finden können. Die Bedeutung jeder Eigenschaft wird einfach zu verstehen sein. Wir schlagen vor, diese Kommentare auch Ihrer Konfigurationsdatei wrapper.conf hinzuzufügen.

# The first application parameter is the name of the class whose main
# method is to be called when the application is launched.  The class
# name is followed by the number of parameters to be passed to its main
# method.  Then comes the actual parameters.
wrapper.app.parameter.1=org.apache.catalina.startup.Bootstrap
wrapper.app.parameter.2=1
wrapper.app.parameter.3=start

# The start parameters are followed by the name of the class whose main
# method is to be called to stop the application.  The stop class name
# is followed by a flag that controls whether or not the Wrapper should
# wait for all non daemon threads to complete before exiting the JVM.
# The flag is followed by the number of parameters to be passed to the
# stop class's main method.  Finally comes the actual parameters.
wrapper.app.parameter.4=org.apache.catalina.startup.Bootstrap
wrapper.app.parameter.5=TRUE
wrapper.app.parameter.6=1
wrapper.app.parameter.7=stop

Die start- und stop-Klassennamen sollten jetzt klar sein. Der erste Parameter Zahl (count) wird benötigt, um die stop-Klasse in der Parameterliste zu finden. Die zweite Zahl exisitiert für die Konsistenz.

Das Flag oben an Parameterstelle #5 wird genutzt, um das Verhalten der WrapperStartStopApp-Helper-Klasse zu steuern, wenn sie die JVM beendet. Wenn der Wrapper eine Beenden-Anforderung an die JVM sendet, antwortet WrapperStartStopApp durch Aufruf der Main-Methode der "stop"-Klasse mit den konfigurierten Parametern. Das Flag oben kontrolliert, was passiert, wenn diese Main-Methode einen Rückgabewert liefert.

Wenn das Flag FALSE ausgibt, wird System.exit(0) sofort aufgerufen. Wenn es TRUE ausgibt, wird WrapperStartStopApp warten, bis alle Non-Daemon- Threads abgeschlossen sind, bevor System.exit(0) aufgerufen wird. Letzteres ist das Verhalten, welches das beste Beenden für Tomcat ermöglicht. Wenn TRUE spezifiziert wird, aber mindestens ein Daemon-Thread noch nicht abgeschlossen ist, wird der Wrapper Das Beenden der JVM erzwingen, nachdem das Time-out des Beendens abgelaufen ist. Das Time-out ist standardmäßig auf 30 Sekunden eingestellt.

Non-Daemon-Threads werden gezählt, indem sie über alle Threads im System iteriert werden und die gezählt werden, deren isDaemon-Methode FALSE zurückgibt. Leider wird diese Zählung in den meisten JVM niemals wirklich "0" (Null) erreichen, da die Systemthreads existieren.

In den meisten Oracle HotSpot JVMs gibt es einen Systemthread, der kein Daemon ist. Damit das Beenden korrekt funktioniert, muss diese Systemthreadzahl auch korrekt sein. Sie kann duch Definieren einer Systemeigenschaft festgelegt werden: org.tanukisoftware.wrapper.WrapperStartStopApp.systemThreadCount Der Standardwert ist "1 Thread".

NOTE

Wenn die Main-Methode der stop-Klasse System.exit von innerhalb seines Hauptthreads aufruft, wird dieser Thread tatsächlich durch diesen Aufruf geblockt. Der Wrapper vermeidet einen Deadlock, indem er diesen entdeckt und mit dem Beenden nach 5 Sekunden fortfährt. Dies kann jedoch in der Anwendung dazu führen, dass es der Anwendung misslingt, sich selbst korrekt zu beenden und sollte wo möglich vermieden werden.

Dieser Fall kann getestet werden, um die Eigenschaft wrapper.debug=TRUE zu aktivieren und dann die Logdatei während des Beenden-Prozesses zu beobachten.

Bibliothekspfad

Um den Wrapper einzusetzen, gibt es eine weitere Eigenschaft, die gesetzt werden muss. Der Wrapper benutzt eine native Bibliothek, um den Austausch mit dem System zu steuern. Diese Bibliotheksdatei libwrapper.so muss im Bibliothekspfad bestimmt werden, der gegenüber der JVM angegeben wird.

Tomcat hat keine eigenen nativen Bibliotheken, aber wenn es diese hätte, müssten die Verzeichnisse, in denen sie sich befinden, auch spezifiziert werden. Der Bibliothekspfad wird durch Festlegen der Eigenschaften wrapper.java.library.path.<n> festgelegt.

wrapper.java.library.path.1=/usr/lib/apache-tomcat-9.0.0.M13/lib

Zusammenfassung

Zusammenfassend erhalten wir Folgendes:

wrapper.java.command=/opt/jdk1.8.0_45/bin/java

wrapper.java.additional.1=-Dcatalina.base=/usr/lib/apache-tomcat-9.0.0.M13
wrapper.java.additional.2=-Dcatalina.home=/usr/lib/apache-tomcat-9.0.0.M13
wrapper.java.additional.3=-Djava.io.tmpdir=/usr/lib/apache-tomcat-9.0.0.M13/temp
wrapper.java.additional.4=-Djdk.tls.ephemeralDHKeySize=2048
wrapper.java.additional.5=-Djava.protocol.handler.pkgs=org.apache.catalina.webresources
#following properties are optional:
wrapper.java.additional.6=-Djava.util.logging.config.file=/usr/lib/apache-tomcat-9.0.0.M13/conf/logging.properties
wrapper.java.additional.7=-Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager

wrapper.jarfile=/usr/lib/apache-tomcat-9.0.0.M13/lib/wrapper.jar

wrapper.java.classpath.1=/usr/lib/apache-tomcat-9.0.0.M13/bin/bootstrap.jar
wrapper.java.classpath.2=/usr/lib/apache-tomcat-9.0.0.M13/bin/tomcat-juli.jar

wrapper.java.library.path.1=/usr/lib/apache-tomcat-9.0.0.M13/lib

wrapper.java.mainclass=org.tanukisoftware.wrapper.WrapperStartStopApp

wrapper.app.parameter.1=org.apache.catalina.startup.Bootstrap
wrapper.app.parameter.2=1
wrapper.app.parameter.3=start
wrapper.app.parameter.4=org.apache.catalina.startup.Bootstrap
wrapper.app.parameter.5=TRUE
wrapper.app.parameter.6=1
wrapper.app.parameter.7=stop

Bitte beachten Sie, dass diese Konfigurationen auf diesem bestimmten Gerät korrekt zwar funktionieren, diese aber sehr stark von der Verzeichnisstruktur und Plattform abhängen können. Durch Nutzen der Tatsache, dass die Skripte des Wrappers stets das aktuelle Verzeichnis auf den Speicherort des Skripts festlegen, und durch Nutzen einer einzelnen Umgebungsvariablen sind wir in der Lage die oben genannten Eigenschaften zu ändern, so dass sie komplett plattform- und maschinenunabhängig sind.

wrapper.java.command=%JAVA_HOME%/bin/java

wrapper.java.additional.1=-Dcatalina.base=..
wrapper.java.additional.2=-Dcatalina.home=..
wrapper.java.additional.3=-Djava.io.tmpdir=../temp
wrapper.java.additional.4=-Djdk.tls.ephemeralDHKeySize=2048
wrapper.java.additional.5=-Djava.protocol.handler.pkgs=org.apache.catalina.webresources
#following properties are optional:
wrapper.java.additional.6=-Djava.util.logging.config.file=../conf/logging.properties
wrapper.java.additional.7=-Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager

wrapper.jarfile=../lib/wrapper.jar

wrapper.java.classpath.1=../bin/bootstrap.jar
wrapper.java.classpath.2=../bin/tomcat-juli.jar

wrapper.java.library.path.1=../lib

wrapper.java.mainclass=org.tanukisoftware.wrapper.WrapperStartStopApp

wrapper.app.parameter.1=org.apache.catalina.startup.Bootstrap
wrapper.app.parameter.2=1
wrapper.app.parameter.3=start
wrapper.app.parameter.4=org.apache.catalina.startup.Bootstrap
wrapper.app.parameter.5=TRUE
wrapper.app.parameter.6=1
wrapper.app.parameter.7=stop

NOTE

Es wurde berichtet, dass Tomcat 5.0.28 nicht korrekt funktionieren wird, wenn das bin-Verzeichnis in der java.endorsed.dirs-Systemeigenschaft enthalten wäre. Dies hat seine Ursache vielmehr in einer Änderung von Tomcat, als dass es ein Problem mit dem Wrapper ist. Bitte ändern Sie die oben genannte Konfiguration wie folgt:

wrapper.java.additional.1=-Djava.endorsed.dirs=../common/endorsed

Testen

Tomcat kann nun einfach durch das Ausführen des Skripts bin/tomcat console ausgeführt werden. Aufgrund der Art, wie der Wrapper sein aktuelles Verzeichnis festlegt, ist es nicht notwendig, das Skript innerhalb des bin-Verzeichnisses auszuführen.

Wie Sie sehen werden, wenn Sie einen Befehl auslassen, sind die mit dem Wrapper ausgelieferten Skripte, ziemliche Standard-Daemon-Skripte. Sie akzeptieren console, start, stop, restart und dump-Befehle. Die start, stop und restart-Befehle sind den meisten Daemon-Skripten geläufig und werden benutzt, um den Wrapper und seine Anwendung als Daemon-Prozess zu steuern. Der status-Befehl kann genutzt werden, um herauszufinden, ob der Wrapper gegenwärtig läuft oder nicht. Der console-Befehl startet den Wrapper in der aktuellen Shell, und macht es so möglich, dass die Anwendung mit STRG-C beendet werden kann. Der letzte Befehl, dump, sendet ein "kill -3"-Signal an den Wrapper, welcher seine JVM veranlasst, einen vollständigen Thread-Dump zu erstellen.

Herzlichen Glückwunsch! Ihre Anwendung sollte jetzt laufen.

Wenn Sie Probleme haben, finden Sie im Abschnitt Troubleshooting Hilfe, zur Lösung des Problems.

Erweiterte Informationen

Tuning des Hochstartens

Standardmäßig wartet die WrapperStartStopApp- Klasse 2 Sekunden auf die Fertigstellung der Main-Methode der User-Anwendung. Danach nimmt sie an, dass die Anwendung gestartet wurde und erstattet einen Bericht an den Wrapper-Prozess. Dies wird gemacht, weil viele User-Anwendungen mit Main-Methoden geschrieben sind, die während der Ausführung der Anwendung keinen Wert zurückgeben. In solchen Fällen gibt es keinen zuverlässigen Weg für die WrapperStartStopApp-Klasse, mitzuteilen, wann und ob die Anwendung das Hochstarten fertiggestellt hat.

Wenn jedoch bekannt ist, dass die Main-Methode der Anwendung einen Wert zurückgibt, sobald die Anwendung gestartet wurde, wäre es für den Wrapper am besten, zu warten bis dies abgeschlossen ist, bevor er die Ausführung fortsetzt.

waitForStartMain Systemeigenschaft:

Für Main-Methoden, die auf diese Art Werte zurückgeben, sucht die WrapperStartStopApp nach der org.tanukisoftware.wrapper.WrapperStartStopApp.waitForStartMain Systemeigenschaft. Wenn sie auf TRUE eingestellt ist, wird die WrapperStartStopApp unbegrenzt auf die Fertigstellung der Main-Methode warten.

Beispiel: (Wartezeit aktivieren)
wrapper.java.additional.1=-Dorg.tanukisoftware.wrapper.WrapperStartStopApp.waitForStartMain=TRUE

maxStartMainWait Systemeigenschaft:

Unendlich zu warten ist eine vorteilhafte Option, wenn gewiss ist, dass die Main-Methode zeitnah antworten wird. Andererseits wird der Wrapper während er unbegrenzt wartet, während des Hochfahrens niemals aufgeben, unabhängig davon, wie lange es dauert.

Wenn die Möglichkeit besteht, dass der Hochstarten-Vorgang hängen könnte, ist es besser, die org.tanukisoftware.wrapper.WrapperStartStopApp.maxStartMainWait Systemeigenschaft auf die maximale Wartezeit einzustellen. Zum Beispiel um bis zu 5 Minuten (300 Sekunden) auf die Fertigstellung der Main-Methode beim Hochstarten zu warten, stellen Sie die Eigenschaft wie folgt auf 300 ein:

Der Standardwert ist "2 Sekunden".

Beispiel: (300 Sekunden)
wrapper.java.additional.1=-Dorg.tanukisoftware.wrapper.WrapperStartStopApp.maxStartMainWait=300

NOTE

Die Main-Methoden vieler Anwendungen sind darauf ausgelegt, keinen Wert zurückzugeben. In diesen Fällen müssen Sie sich entweder an die üblichen 2-Sekunden-Timeoutzeit beim Hochstarten halten oder ein etwas längeres Timeout festlegen, indem Sie die maxStartMainWait-Eigenschaft nutzen, um die Zeit zu simulieren, die Ihre Anwendung zum Hochstarten benötigt.

WARNING

Wenn "TRUE" in der waitForStartMain für eine Anwendung festgelegt ist, deren start-Methode niemals einen Wert zurückgibt, erscheint der Wrapper zu Anfang korrekt zu funktionieren. Der Wrapper befindet sich dann jedoch in einem ewig andauernden Wartestatus und wird nie in einen Start-Modus kommen, in dem Ihre Anwendung überwacht werden kann.