Betrieb von Wicket-Anwendungen
Deployment in Tomcat I
-
Wicket-Anwendungen funktionieren in jedem Servlet-Container, häufig verwendet werden Apache Tomcat, Jetty oder Glassfish.
-
Tomcat muss lediglich entpackt und gestartet werden:
cd bin/ sh startup.sh -
Die Konsolenausgaben des Tomcat-Prozesses können verfolgt werden mit:
tail logs/catalina.out
Deployment in Tomcat II
-
WAR-Archive können durch Kopieren in den
webapps-Ordner oder mit der Manager-Anwendung deployt werden. -
Um den Tomcat Manager zu verwenden, muss unter
conf/tomcat-users.xmlein Benutzer mit der Rollemanagereingerichtet werden:<tomcat-users> <role rolename="manager"/> <user username="tomcat" password="secret" roles="manager"/> </tomcat-users>
-
Maven baut mit
mvn package(in EclipseRun As > Maven package) einWAR-Archiv, da in derpom.xmlalspackaging-Formatwarangegeben ist:mvn package
Wicket läuft standardmäßig im development-Modus
- Markup-Dateien werden beobachtet und bei Änderungen neu geladen.
- Es greifen sehr strikte Fehlerprüfungen und Validierungen.
- Bei Fehlern wird der vollständige Stack-Trace angezeigt.
<wicket>-Tags verbleiben im Markup.- Es finden keine Optimierungen wie Caching oder Komprimierung statt.
Konfiguration development / deployment
-
Der
deployment-Modus kann über einen Initialisierungsparameter für denWicket-Filteraktiviert werden:<init-param> <param-name>configuration</param-name> <param-value>deployment</param-value> </init-param>
-
Alternativ kann auf Produktivumgebungen beim Starten der JVM eine System-Property gesetzt werden, z.B. für Tomcat:
export CATALINA_OPTS="-Dwicket.configuration=deployment"
Tipps und Tricks: Maven Profile
-
Maven unterstützt
Profile, mit denen ein Build angepasst werden kann. So können z.B. abhängig vom Profil zusätzliche Dateien ergänzt werden. Dies kann auch für “Konfigurationsprofile” der Anwendung verwendet werden. -
Das zu verwendende Profil kann beim Build angegeben werden:
mvn package -P production
Beispiel Maven-Profile I
<profiles>
<profile>
<id>dev</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<build>
<resources>
<resource>
<directory>src/conf/dev</directory>
<includes><include>**/*</include></includes>
</resource>
</resources>
</build>
</profile>
<!-- ... -->
</profiles>
Beispiel Maven-Profile II
<profile>
<id>production</id>
<build>
<resources>
<resource>
<directory>src/conf/production</directory>
<includes><include>**/*</include></includes>
</resource>
</resources>
<plugins> <!-- Keine Tests auf Produktionsumgebung -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration><skip>true</skip></configuration>
</plugin>
</plugins>
</build>
</profile>
Tomcat, Apache 2 und mod_jk
-
Für große oder öffentliche Installationen empfiehlt es sich, den eigentlichen Applikationsserver mit einem
Apache 2-Webserver abzuschirmen. Dies erlaubt insbesondere eine einfachere Konfiguration von Caching, Clustering, HTTPS und Virtual Hosts. -
Dazu ist in der Tomcat-Konfiguration
conf/server.xmlein AJP-Connector zu definieren:<!-- Define an AJP 1.3 Connector on port 8009 --> <Connector port="8009" enableLookups="false" redirectPort="8443" protocol="AJP/1.3" />
Tomcat, Apache 2 und mod_jk: mod_jk.conf, workers.properties
-
In der Apache-Konfiguration ist das Modul
mod_jkzu aktivieren und in dermod_jk.confeine Workerkonfiguration zu hinterlegen, z.B.:<IfModule mod_jk.c> JkWorkersFile /etc/apache2/workers.properties JkLogFile /var/log/apache2/mod_jk.log JkLogLevel error </IfModule>
-
In der
workers.propertieswird ein Worker je Anwendung definiert:workers.tomcat_home=/usr/share/tomcat5.5/ workers.java_home=/usr/lib/jvm/java-6-sun/jre/ ps=/ worker.list=mainworker worker.mainworker.type=ajp13 worker.mainworker.port=8009 worker.mainworker.cachesize=20
Tomcat, Apache 2 und mod_jk: JkMount
-
Mit
JkMountkönnen URLs an Worker weitergeleitet werden, z.B. in Virtual Host-Direktiven:<VirtualHost _default_:80> ServerName www.example.com ServerAdmin johnq@example.com JkMount /* mainworker ErrorLog /var/log/apache2/error.log LogLevel warn CustomLog /var/log/apache2/access.log combined </VirtualHost>
Logging
-
Wicket verwendet zum Logging
slf4j. Dabei handelt es sich um eine Logging-Facade, die an alle gängigen Logging-Frameworks weiterdeligieren kann. -
Für den QuickStart-Archetypen wird standardmäßig
Log4jverwendet, das überlog4j.propertiesim Package-Root konfiguriert wird. -
Logging von Requests mit Antwortzeiten kann in der Applikationsklasse aktiviert werden:
@Override protected void init() { getRequestLoggerSettings().setRequestLoggerEnabled(true); }
log4j.properties mit rotierender Log-Datei und E-Mail-Alarm
log4j.appender.EMAIL=org.apache.log4j.net.SMTPAppender
log4j.appender.EMAIL.Threshold=ERROR
log4j.appender.EMAIL.BufferSize=10
log4j.appender.EMAIL.To=johnq@example.com
log4j.appender.EMAIL.From=someapp@example.com
log4j.appender.EMAIL.SMTPHost=smtp.example.com
log4j.appender.EMAIL.Subject=[someapp] Error Log
log4j.appender.EMAIL.layout=org.apache.log4j.PatternLayout
log4j.appender.EMAIL.layout.ConversionPattern=%5p [%t] (%F:%L) - %m%n
log4j.appender.FILE=org.apache.log4j.DailyRollingFileAppender
log4j.appender.FILE.File=/var/log/someapp.log
log4j.appender.FILE.DatePattern='.'yyyy-MM-dd
log4j.appender.FILE.layout=org.apache.log4j.PatternLayout
log4j.appender.FILE.layout.ConversionPattern=%d{HH:mm:ss} [%-16t] %-5p %-45.45c (%-3L) - %m%n
log4j.rootCategory=INFO, FILE, EMAIL
Best Practice: Commons Logging vermeiden
-
Commons Logging ist bekannt dafür, Class Loading-Probleme in Servlet-Containern zu verursachen.
-
slf4jbietet auch das Commons Logging API an, welches als Ersatz verwendet werden sollte:<!-- include jcl-over-slf4j --> <dependency> <groupId>org.slf4j</groupId> <artifactId>jcl-over-slf4j</artifactId> <version>1.5.8</version> </dependency>
Best Practice: Commons Logging vermeiden II
<!-- exclude commons-logging for some other dependency -->
<dependency>
<groupId>someGroupId</groupId>
<artifactId>someArtifactId</artifactId>
<version>1.0.0</version>
<exclusions>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
Fehlerbehandlung
-
Fehlerseiten können über die Applikationsklasse konfiguriert werden:
@Override protected void init() { getApplicationSettings().setInternalErrorPage(SomeErrorPage.class); getApplicationSettings().setAccessDeniedPage(SomeAccessDeniedPage.class); getApplicationSettings().setPageExpiredErrorPage(ExpiredPage.class); }
-
Best Practice: Fehlerseiten im Anwendungsdesign gestalten, evt. ein Bug-Reporting-System einbinden, damit Fehler von Anwendern gemeldet werden können.
-
ExpiredPageevt. auf die Startseite der Anwendung setzen, um Anwender nicht explizit mit abgelaufenen Sessions zu konfrontieren.
URLs
-
Es empfiehlt sich, wo immer es möglich ist, lesezeichen-fähige URLs (
BookmarkablePage) zu verwenden und diese URLs möglichst stabil zu halten (Lesezeichen sollten für lange Zeiträume gültig sein.) -
Seiten können in der Anwendungsklasse mit
mountBookmarkablePageauf URLs gemappt werden, z.B.:@Override protected void init() { mountBookmarkablePage("/cars", CarPage.class); }
-
Dabei kommt standardmäßig eine Strategie zum Einsatz, die Parameter in die URL selbst integriert, z.B.:
http://localhost:8080/cars/id/3/


Besser zum Verfolgen der Logausgaben, wenn schon auf der Kommandozeile, wäre "tail -f" statt einfach nur "tail".