Das Wissensportal für IT-Professionals. Entdecke die Tiefe und Breite unseres IT-Contents in exklusiven Themenchannels und Magazinmarken.

SIGS DATACOM GmbH

Lindlaustraße 2c, 53842 Troisdorf

Tel: +49 (0)2241/2341-100

kundenservice@sigs-datacom.de

Apache Tomcat 10.1 – sagt Hallo zu Jakarta EE und Kubernetes

Da es noch viele Java EE-Webanwendungen gibt, stellt sich die Frage, wie diese die neuen Webstandards wie HTTP/3 unterstützen können. Mit Tomcat 10.1 liegt eine Umsetzung neuer Standards wie Jakarta EE 9.1 vor. Es ist sogar möglich, diesen als natives GraalVM oder als einen Kubernetes-Cluster laufen zu lassen. Der Artikel stellt die Neuerungen und die Schritte für eine Migration zur Version 10.1 [MIG] vor.
Author Image
Frank Pientka

Principal Software Architect


  • 28.01.2022
  • Lesezeit: 19 Minuten
  • 83 Views

Still alive

Als einer der ersten Java-Applikationsserver ist Tomcat [Pien16] immer noch weit verbreitet. Nur weil seine Ursprünge noch aus dem letzten Jahrtausend stammen, bedeutet das nicht, dass er sich über die Jahre nicht weiterentwickelt hat. Als wichtigste minimale Anforderung wird jetzt eine Java 11-Laufzeitumgebung benötigt, auch wenn neuere Java-Versionen ebenfalls unterstützt werden. Auch die grundsätzlichen Anforderungen eines Webservers, wie gute Kompatibilität zu Standards (W3C, Java EE), Integrierbarkeit (Datenbanken, LDAP, Mail, REST), Überwachbarkeit (JMX), aber auch Sicherheit und Skalierbarkeit, spielen eine große Rolle (s. Abb. 1).

Bei der Bedienbarkeit kann Tomcat zwar nicht mit einer umfangreichen Administrations-Oberfläche aufwarten. Dafür glänzt diese durch Einfachheit und die Möglichkeit, sie auch rein textuell mit REST zu verwenden. Die Dokumentation [Tomcat] ist umfangreich, bietet bei den inzwischen vielen Konfigurationsmöglichkeiten jedoch zu wenig Beispiele, um schnell eine passende Kombination zu finden.

Wichtig für Java- und Java EE-Anwendungen ist eine gute Kompatibilität zu alten und neuen Standards. Auch wenn Tomcat nicht mehr die Referenzimplementierung für die Servlet-Spezifikation ist, sind seine Entwickler immer bemüht, eine aktuelle Unterstützung zu liefern. Erst recht, da jetzt unter dem Dach der Eclipse-Stiftung mit Jakarta EE die Nachfolge-Spezifikation von Java EE zusammen mit dem TCK frei verfügbar ist. Tabelle 1 zeigt die aktuellen Versionen. Wichtig ist, dass Tomcat 10.1 die erste Version ist, die ausschließlich auf den Jakarta EE-Paketnamen beruht.

Abb. 1: Anforderung an Web-Applikationsserver

Tabelle 1: Von Tomcat 10.1 unterstützte Standards
Veröffentlicht in Servlet, JSP, EL Version von Java, EL JDBC, TLS sowie WS
2021 5.0, 3.0, 5.0 Java 11+, Jakarta 9.1, WebSocket 2.1, CDI 2.0, JAX-RS 3.1, JASPIC 2.0, GraalVM 17

Jakarta EE ready

Wer einfache Java EE-Anwendungen einsetzt, kann für diese mit dem, auch separat erhältlichen, Migrationswerkzeug [JakartaEEm] migrate.bat [options] <source> <destination> selbst die Namensräume von javax.* zu jakarta.* anpassen lassen, um Java EE 8-Anwendungen zu Jakarta EE 9 zu migrieren. Alternativ lässt sich unter CATALINA_ HOME ein Ordner webapps-javaee erstellen und dort die JEE-WAR-Datei hineinkopieren. Ein laufender Tomcat nimmt dann die Umwandlung in eine Jakarta-WAR-Datei im Ordner webapps vor und deployt diese auch. In der Regel funktioniert das Ersetzen der Paketnamen in JSPs und in den XML-Deployment-Dateien gut. Bei den JARs werden einfach die benötigten Jakarta-Klassen in die jeweiligen Bibliotheksarchive wie bei jstl-1.2.jar kopiert.

Da nicht alle JAR-Archive TLD-Dateien (Tag Library Descriptor) enthalten, kann es sinnvoll sein, diese aus dem Standard-Scanner-Prozess von Tomcat herauszunehmen. Dazu kann man in der catalina.properties diese Dateien in die Weiße Liste hinter tomcat.util. scan.StandardJarScanFilter.jarsToSkip=\ aufnehmen. Das funktioniert entweder mit dem kompletten Namen oder mit Wildcards wie beispielsweise für die Apache Derby JDBC-Treiber-Dateien mit derby-*.jar. Bei größeren Anwendungen, wie zum Beispiel mit dem Spring Framework, sind es viele JAR-Dateien. Diese kann man sich mit einer genaueren Protokolleinstellung org.apache.jasper.servlet.Tld-Scanner.level = FINE in der Datei logging.properties ausgeben lassen. Hilfreicher ist das Shell-Skript in Listing 1, dessen Ausgabe man nach Überarbeitung und Prüfung in die catalina.properties-Datei kopiert, womit man unnötiges Scannen vermeidet. Alternativ kann man auch das komplette TLD-Dateien-Scannen in der conf\context.xml-Datei deaktivieren, was jedoch in vielen Fällen keine befriedigende Lösung ist (s. Listing 2).

#!/bin/sh
TOMCAT_HOME=/opt/tomcat
for i in `find $TOMCAT_HOME -follow -name "*jar"`
do
jar tvf $i | grep -i tld > /dev/null
if [ $? -eq 0 ]; then
echo "$(basename $i),\\"
fi
done
Listing 1: Shell-Skript


<Context>
<!-- only if you do not use jsp tag -->
<JarScanner>
<JarScanFilter defaultPluggabilityScan="false"
defaultTldScan="false"/>
</JarScanner>
</Context>
Listing 2: defaultTldScanner deaktivieren

Bei größeren Java EE-Anwendungen führen weder diese Einstellungen noch das Migrationswerkzeug zum Erfolg, sodass man selbst Hand anlegen muss, um zu Jakarta zu wechseln. So muss man zum Beispiel bei der Migration von Apache Roller migrate.bat -zipInMemory roller.war roller9.war den -zipInMemory-Parameter angeben. Das Deployment funktioniert dann, jedoch lässt sich die Anwendung in Tomcat 10.1 nicht aufrufen. Eine einfache Spring-MVC-Anwendung haben wir in den Ordner webapps-javaee kopiert, die dann automatisch nach webapps migriert wurde und unter http://localhost:84080/myapp/ erfolgreich aufrufbar war. Diese können Sie selbst mit folgenden Aufrufen erstellen und als WAR-Datei packen lassen:

mvn archetype:generate -DgroupId="com.mycompany.app" \
 -DartifactId="myapp" -DarchetypeGroupId="org.springframework.boot" \
 -DarchetypeArtifactId="spring-boot-sample-web-jsp-archetype" \
 -DarchetypeVersion="1.0.2.RELEASE" -DinteractiveMode=false
mvn package

Was ändert sich? Adieu

Tomcat versucht immer wieder, eine Balance zwischen Stabilität und Innovation zu finden. So werden mit der Version 10.1 einige Altlasten beseitigt. Das betrifft vor allem die Connectoren. So wird das Java Network Block-IO nicht mehr unterstützt, da die Alternative NIO dieses inzwischen abgelöst hat. Bisher wurde aus Performanzgründen die Apache Portable Runtime (APR) mit OpenSSL verwendet. So hat sich seit Version APR 1.7 seit Langem nichts mehr getan. Da mit Java 17 und dem JEP 412 das umständliche Java Native Interface (JNI) zum Aufruf von C-Funktionen durch eine neue, rein auf Java basierende Programmierschnittstelle abgelöst wird, ist es nicht mehr als konsequent, APR mit dieser Version abzukündigen. Damit spart sich Tomcat in Zukunft den Pflegeaufwand für die Apache Tomcat Native Library. Mit Java 17 kann OpenSSL durch das Panama API jetzt schon ohne APR verwendet werden. Nur wenn Sie für die Validierung Ihrer Zertifikate das Online Certificate Status Protocol (OCSP) verwenden möchten, benötigen Sie weiterhin OpenSSL mit dem Apache Tomcat APR Connector, da JSSE diese Möglichkeit nicht anbietet.

Da die vom JreMemoryLeakPreventionListener behandelten Speicherlöcher ab Java 11 nicht mehr existieren, kann dies aus der server.xml entfernt werden. Auch wenn die neue WebSocket-Version aus Kompatibilitätsgründen unterstützt wird, werden die meisten Projekte eher auf das modernere HTTP/2-Protokoll umstellen.

Sichere Übertragung

Wenn man sich die Verbreitung der HTTPS-Verschlüsselung im Web anschaut, gibt es hier einen klaren Trend zu neuen TLS-Versionen. Nach einer Auswertung von [SSLPULSE] im November 2021 ist TLS 1.2 mit 99,6 Prozent aller Webseiten klar am meisten verbreitet (s. Abb. 2). Das 2017 standardisierte TLS 1.3 mit 50,4 Prozent hat inzwischen TLS 1.1 mit 44,3 Prozent überholt. Seit April 2021 sind TLS 1.1 und 1.0 in der java.security-Datei bei neueren Java-Versionen deshalb bereits deaktiviert:

jdk.tls.disabledAlgorithms=SSLv3, TLSv1, TLSv1.1, RC4, DES, MD5withRSA, \
 DH KEYSIZE < 1024, EC KEYSIZE < 224, 3DES_EDE_CBC, ANON, NULL
# with TLS 1.3 only.
jdk.tls.keyLimits=AES/GCM/NoPadding KeyUpdate 2^37


Das HTTP/3-Protokoll [HTTP3], das 2021 standardisiert wurde und TLS 1.3 voraussetzt, wird inzwischen von fast allen Browsern [CANI] unterstützt und von großen Cloud-Anbietern wie Cloudfare, Akamai oder Google verwendet. Da der Schlüsselaustausch beim Handschlag auf eine Phase verkürzt wurde, ist der Verbindungsaufbau insgesamt beschleunigt und es können schneller kleinere Häppchen ausgetauscht werden. Das kommt gerade mobilen Anwendungen zugute.

Abb. 2: TLS-Versionsverteilung [SSLPULSE]

Die meisten Programmiersprachen und Webserver unterstützen zwar TLS 1.3, hinken jedoch bei dem HTTP/3-Protokoll hinterher (s. Abb. 3). Dieses benötigt zwar auch TLS 1.3, doch zusätzlich das QUIC-Protokoll [QUIC]. OpenSSL 1.1.1 unterstützt zwar TLS 1.3. Neuere Standards wie FIPS 140 werden erst in OpenSSL 3.x umgesetzt. Da für das Streaming mit QUIC die OpenSSL-API erst geändert werden muss, gibt es mit QuicTLS [QuicTLS] einen Fork von OpenSSL, der HTTP/3 unterstützt und zum Beispiel auch von .NET 6 mit MsQuic verwendet wird. Für Java SE ist HTTP/3 noch kein Thema. Immerhin wird mit Java 11.0.15 TLS 1.3 als Default aktiviert. Wer HTTP/3 mit Java jetzt schon verwenden möchte, kann die Bibliotheken Quiche4j oder Kwik verwenden.

Ein Problem bei der parallelen Verwendung von TLS 1.2 und 1.3 ist, dass die Chiffren-Sammlungen, anders als bei den Vorgängerversionen, ein anderes Namensschema haben, da der Protokollablauf auch anders ist. Das kann man wie im Kasten „Chiffren-Sammlungen” zusammenfassen. TLS 1.2 Chiffren-Sammlungen haben drei Verschlüsselungs- und einen Hash-Algorithmus. Bei TLS 1.3 sind es nur ein Verschlüsselungs- und ein Hash-Algorithmus.

Wer wissen möchte, welche Chiffren für die verschiedenen TLS-Versionen empfohlen werden, findet unter https://ciphersuite.info/ die passenden Informationen und kann sich für die Implementierung OpenSSL und GnuTLS die korrekte Syntax anzeigen lassen. Um zu testen, welche Chiffren die installierte OpenSSL oder Java-Version unterstützt, und um zu entscheiden, ob man TLS 1.3 verwenden kann, ruft man openssl ciphers -s -v -tls1_3 auf.

Abb. 3: HTTP/2- und HTTP/3-Protokoll im Vergleich

Bei Tomcat gibt es hierfür das Werkzeug ciphers.bat. Mit version.bat kann man sich die verwendete Tomcat- und Java-Version anzeigen lassen. Um Tomcat nur für TLS 1.3 und HTTP/2 zu konfigurieren, muss der HTTPS-Connector in der server.xml-Datei angepasst werden. Wir gehen davon aus, dass bereits ein gültiges Zertifikat in der Keystore-Datei localhost-rsa.jks hinterlegt ist (s. Listing 3).
Um zu überprüfen, ob die Konfiguration syntaktisch korrekt ist, rufen Sie CATALINA_HOME\bin\configtest.bat auf. Um zu überprüfen, ob die Konfiguration inhaltlich korrekt ist, können Sie das entweder mit Browser-Tools oder einfach mit openssl s_client -connect localhost:8443 -tls1_3 tun. Mit der Tomcat-Manager-Anwendung kann man die SSL-Konfiguration und die dabei verwendeten Zertifikate mit folgenden Aufrufen überprüfen oder Änderungen dazu neu laden:

http://localhost:8080/manager/text/sslConnectorCiphers
http://localhost:8080/manager/text/sslConnectorCerts
http://localhost:8080/manager/text/sslConnectorTrustedCerts
http://localhost:8080/manager/text/sslReload

<Connector port="8443"
      protocol="org.apache.coyote.http11.Http11NioProtocol"
      maxThreads="150" SSLEnabled="true" >
    <UpgradeProtocol className="org.apache.coyote.http2.Http2Protocol"
/>
    <SSLHostConfig honorCipherOrder="true"
ciphers=
  "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_AES_256_
GCM_SHA384,
  TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDH_ECDSA_WITH_AES_256_GCM_
SHA384,
  TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_AES_128_
GCM_SHA256,
  TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDH_ECDSA_WITH_AES_128_GCM_
SHA256,
  TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384,TLS_ECDHE_ECDSA_WITH_AES_256_
CBC_SHA384,
  TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_ECDSA_WITH_AES_256_CBC_
SHA,
  TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384,TLS_ECDH_ECDSA_WITH_AES_256_CBC_
SHA384,
  TLS_ECDH_RSA_WITH_AES_256_CBC_SHA,TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA,
  TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,TLS_ECDHE_ECDSA_WITH_AES_128_
CBC_SHA256,
  TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_ECDSA_WITH_AES_128_CBC_
SHA,
  TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256,TLS_ECDH_ECDSA_WITH_AES_128_CBC_
SHA256,
  TLS_ECDH_RSA_WITH_AES_128_CBC_SHA,TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA,
  TLS_AES_128_GCM_SHA256,TLS_AES_256_GCM_SHA384,TLS_RSA_PSK_WITH_
CHACHA20_POLY1305_SHA256"
  protocols="TLSv1.3+TLSv1.2">
  <Certificate certificateKeystoreFile="conf/localhost-rsa.jks"
type="RSA" />
    </SSLHostConfig>
</Connector>
Listing 3: HTTPS-Connector anpassen

Sichere Credentials

Ein Problem mit Zugangsdaten ist, dass diese möglichst vor einem unbefugten Zugriff geschützt werden müssen. Deswegen sollte man keine Klartext-Passwörter verwenden. Hier gibt es mit dem digest.bat-Werkzeug von Tomcat die Möglichkeit, Passwörter zu hashen. Die wichtigsten Parameter sind [-a <algorithm>] [-i <iterations>] [-s <salt-length>] [-k <key-length>] <credentials>.

Der MessageDigestCredentialHandler unterstützt neben Klartext auch Base64 encoded MD5 und SHA1 Digests. Die SHA1 Digests können auch mit einem Salz mit 20 Zeichen versehen werden. Als Standardalgorithmus wird SHA-512 mit einer Salzlänge 32 und einer Iteration verwendet. Wenn wir also digest.bat s3cret aufrufen, ist das identisch mit digest.bat -i 1 -s 1 s3cret.

Das Digest wird im Format {salt}${iterations}${digest} ausgegeben, wenn Salzlänge und Iteration nicht o sind. Ein guter Kompromiss zwischen Sicherheit und Ausführungsgeschwindigkeit ist folgender MD5-Digest:

digest.bat -a md5 -s 16 -i 10000 s3cret

Ein etwas sicherer Algorithmus ist PBKDF2, den wir wie folgt verwenden können:

digest.bat -a PBKDF2WithHmacSHA512 -i 10000 -s 16 -k 256 -h

Damit Tomcat diesen für seine Realms verwenden kann, müssen wir die server.xml anpassen. Seit Tomcat 8 wird der Digest-Algorithmus über einen CredentialHandler definiert. In unserem Fall wird für die beiden Algorithmen MD5 und PBKDF2 ein eigener CredentialHandler definiert. Die conf/server.xml sieht wie in Listing 4 aus. Die gehashten MD5- und PBKDF2-Passwörter für die Manager-Anwendungen kopieren wir dann in die Datei tomcat-users.xml (s. Listing 5).

<Realm className="org.apache.catalina.realm.UserDatabaseRealm"
    resourceName="UserDatabase">
  <CredentialHandler
    className="org.apache.catalina.realm.NestedCredentialHandler">
  <CredentialHandler
    className="org.apache.catalina.realm.SecretKeyCredentialHandler"
    algorithm="PBKDF2WithHmacSHA512" saltLength="16" iterations="10000"
      keyLength="256" >
  <CredentialHandler
    className="org.apache.catalina.realm.MessageDigestCredentialHandler"
    algorithm="MD5" />
  </CredentialHandler>
</Realm>
Listing 4: conf/server.xml
conf/tomcat-users.xml
<?xml version="1.0"?>
<tomcat-users>
<user username="tomcat-old" password=
"s3cret:b998c0910692ac3de598f507c07a5675$10000$595
4827c2b76079d6472448e3e4741f3 "
  roles="manager-gui"/>
<user username="tomcat-new" password=
"d4819946eb426e11bc4e61391e2752f7$10000$6695189fb49c3278d
8ad01ab3ab5c85a8943b0afa3d1cba1f1dcfdf251a1dc67 "
  roles="manager-gui"/>
</tomcat-users>
Listing 5: tomcat-users.xml

Sichere Cluster

Meistens wird Tomcat als Cluster mit einem vorgeschalteten HTT-PD-Web-Proxy verwendet, der als Lastverteiler dient. Die Kommunikation zwischen HTTPD und Tomcat kann entweder über HTTP oder das proprietäre und binäre Apache JServ (AJP)-Protokoll erfolgen. Das AJP-Protokoll kann entweder über das mod_proxy_ajp oder das mod_jk-Modul verwendet werden. Da man das mod_jk-Modul im Gegensatz zum mod_proxy_ajp-Modul nachinstallieren und selbst compilieren muss, verwenden wir hier das mod_proxy_ajp-Modul. Die Kommunikation über den Port 8009 kann zwischen HTTPD und Tomcat über ein vorher geteiltes Geheimwort („sicher“) abgesichert werden, was inzwischen die Standardeinstellung des AJP-Konnektors ist. Dazu wird die Datei server.xml angepasst:

<Connector protocol="AJP/1.3"
 address="0.0.0.0"
 port="8009" secret="sicher" secretRequired="true"
 redirectPort="8443" />


In der httpd.conf-Datei wird der AJP13-Proxy geladen und dessen Konfiguration in der Datei httpd-ajp.conf vorgenommen:

httpd.conf
<IfModule mod_proxy.c>
 <IfModule mod_proxy_ajp.c>
   Include "conf/extra/httpd-ajp.conf"
</IfModule>
</IfModule>
conf/extra/httpd-ajp.conf
ProxyPass /manager ajp://127.0.0.1:8009/manager secret=sicher


Die Konfiguration können Sie mit http://localhost/server-info?mod_ proxy.c testen. Die Weiterleitung an die Manager-Anwendung ist dann mit https://localhost/manager identisch zu https://localhost:8443/manager.

Kubernetes cluster ready

Da heute statt Applikations-Containern oft Linux-Container verwendet werden, stellt sich auch für Tomcat die Frage, wie er in einer Cloud-nativen Umgebung wie Kubernetes [KUBE] betrieben werden kann. Ein zustandsloser Tomcat-Cluster mit einem vorgeschalteten Lastverteiler ist auch mit Kubernetes ohne Probleme möglich. Über die Text-Oberfläche kann einfach der Gesundheitszustand von Tomcat oder seinen Anwendungen mit:

http://localhost:8080/manager/text/serverinfo
http://localhost:8080/manager/status/all

abgefragt werden. Anders sieht es aus, wenn man einen Tomcat-Cluster mit Zustandsreplikation über SimpleTcpCluster mit den Bibliotheken catalina-tribes.jar und catalina-ha.jar betreiben möchte. Bisher basiert die Session-Replikation bei Tomcat auf dem UDP-Multicast-Verfahren (org.apache.catalina.cluster.mcast.McastService). Da jedoch das Standardnetz-Plug-in für Kubernetes kein Multicast unterstützt, müsste man dafür ein anderes Netz-Plug-in wie Calico installieren.

Um eine Tomcat-Zustandsreplikation mit Kubernetes zu verwenden, gibt es zwei Lösungen, die noch in einem recht frühen Stadium sind. Entweder verwendet man KubePing, um den Zustand der Cluster-Knoten abzufragen, oder man fragt über DNSPing (org.apache.catalina.tribes.membership.cloud.DNSMembershipProvider) und die kubectl-API (org.apache.catalina.tribes.membership.cloud.KubernetesMembershipProvider) die DNS-Namen der aktiven Knoten an.

Für den DNSPing muss die server.xml für jeden Knoten um einen neuen Mitgliedsservice erweitert werden. Dieser wird dann über die Service-Deployment-Beschreibung Kubernetes bekannt gegeben (s. Listing 6). Um den Kubernetes Pods als Netzwerkdienst zu exponieren, müssen wir die Service-Definition aus Listing 7 deployen.

<Service ...
  <Engine ...
    <Host ...
      <Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster">
        <Channel className=
"org.apache.catalina.tribes.group.GroupChannel">
          <Membership className=
"org.apache.catalina.tribes.membership.cloud.CloudMembershipService"
        membershipProviderClassName=
"org.apache.catalina.tribes.membership.cloud.DNSMembershipProvider"/>
        </Channel>
      </Cluster>
...
Listing 6: DNSPing
dns-membership-service.yml
  apiVersion: v1
  kind: Service
  metadata:
    annotations:
      service.alpha.kubernetes.io/tolerate-unready-endpoints: "true"
      description: "The service for tomcat cluster membership."
    name: my-tomcat-app-membership
  spec:
    clusterIP: None
    ports:
      - name: membership
        port: 8888
        selector:
          app: my-tomcat-app
Listing 7: Kubernetes Pods als Netzwerkdienst

Von Bitnami gibt es ein Tomcat Helm Chart [HELM], das die Installation und Konfiguration von Tomcat in Kubernetes vereinfacht. Für den Betrieb in Kubernetes gibt es bereits erste Operator-Implementierungen, die die Verwendung von Tomcat weiter vereinfachen sollen. Diese wird von RedHat-Entwicklern für Open-Shift vorangetrieben. Um die Startzeiten von Tomcat zu reduzieren, gibt es auch die Möglichkeit, Cloud-native GraalVM/Mandrel Images [GRAAL] von Tomcat und seinen Anwendungen zu erstellen. Die meisten Funktionen werden unterstützt, jedoch wird statt JULI-Logger nur noch der java.util.logging-Logger unterstützt. Eine Unterstützung für JMX gibt es natürlich nicht, sodass auf die Verwendung des JMX-Lauschers verzichtet werden muss.

Es tut sich etwas bei Tomcat im Bereich Cloud-native und Kubernetes, die ersten Implementierungen sind jedoch noch weit davon entfernt, auch in Produktion eingesetzt werden zu können.

Fazit

Inzwischen sind die Apache Tomcat-Versionen 7.0.x und 8.0.x aus der Wartung gelaufen, sodass als wichtigste Version für Java EE-Webanwendungen 9.0.x bleibt. Die Verwendung von HTTP/3 mit Tomcat wird davon abhängen, wann OpenSSL 3.0 das QUIC-Protokoll implementiert oder aus den bereits existierenden Forks integriert. Für diejenigen, die sich bereits auf den Umstieg auf Jakarta EE vorbereiten wollen, ist die 10.1.x-Version ein guter Startpunkt. Selbst wenn im Jahr 2022 mit der Jakarta EE 10-Version [JakartaEE10] die Verbreitung von Jakarta EE zunehmen wird, wird es noch einige Jahre dauern, bis mehr Projekte auf diese Versionen umsteigen, da es doch ein höherer Aufwand ist, bis vor allem die Fremdbibliotheken auf Jakarta umgestellt sind.

Mit der Unterstützung von Jakarta EE ist Tomcat 10.1 gut aufgestellt und auch etwas Cloud-nativer geworden. Doch auch hier wird es noch einige Zeit dauern, bis bestehende Webprojekte diesen Standard unterstützen werden. Deswegen bleibt auf lange Sicht mit Tomcat 9 doch alles beim Alten, wenn es auch immer wieder Rückportierungen von neuen Funktionen von Tomcat 10 geben wird, wie es bereits in der Vergangenheit üblich war.

Um eine spätere Migration oder ein Update zu vereinfachen, lohnen sich dennoch der Blick und die Vorbereitung auf die Zukunft. So lassen sich viele der hier besprochenen Funktionen auch jetzt schon einsetzen. Viel Erfolg dabei.

Chiffren-Sammlungen

Weitere Informationen

[CANI] Unterstützung TLS1.3, HTTP/3 in Browsern, https://caniuse.com/tls1-3, https://caniuse.com/http3

[GRAAL] Tomcat mit GraalVM, https://tomcat.apache.org/tomcat-10.1-doc/graal.html

[HELM] Tomcat Helm Chart, https://github.com/bitnami/charts/tree/master/bitnami/tomcat, https://github.com/bitnami/bitnami-docker-tomcat#configuration

[HTTP3] Hypertext Transfer Protocol Version 3, https://quicwg.org/base-drafts/draft-ietf-quic-http.html

[JakartaEE10] Jakarta EE 10 Release Plan, https://eclipse-ee4j.github.io/jakartaee-platform/jakartaee10

[JakartaEEm] Apache Tomcat migration tool for Jakarta EE, https://github.com/apache/tomcat-jakartaee-migration

[KUBE] Apache Tomcat unter Kubernetes, https://github.com/jfclere/tomcat-Kubernetes, https://github.com/web-servers/tomcat-operator, https://github.com/kube-incubator/tomcat-operator, https://github.com/java-operator-sdk/tomcat-operator, https://github.com/jfclere/tomcat-openshift

[MIG] Apache Tomcat Migration Guides, https://tomcat.apache.org/migration.html

[Pien16] F. Pientka, Apache Tomcat 9 – zu Protokoll bitte, in: JAVASPEKTRUM, 01/2016

[QUIC] QUIC: A UDP-Based Multiplexed and Secure Transport RFC 9000, https://datatracker.ietf.org/doc/html/rfc9000

[QuicTLS] OpenSSL fork mit QUIC, https://github.com/quictls/openssl

[SSLPulse] SSL Pulse-Statistiken, https://www.ssllabs.com/ssl-pulse/

[Tomcat] Tomcat-Dokumentation, http://tomcat.apache.org/tomcat-10.1-doc, https://tomcat.apache.org/tomcat-10.1-doc/cluster-howto.html, http://tomcat.apache.org/tomcat-10.1-doc/realm-howto.html#Digested_Passwords, http://tomcat.apache.org/tomcat-10.1-doc/config/credentialhandler.html

. . .

Author Image

Frank Pientka

Principal Software Architect
Zu Inhalten

Frank Pientka arbeitet als Principal Software Architect bei der MATERNA SE. Dort sorgt er für mehr Qualität in der Software und kümmert sich als Gründungsmitglied des iSAQB um eine verbesserte Ausbildung und Zertifizierung von Architekten. Seit mehr als drei Jahrzehnten unterstützt er Firmen bei der Umsetzung effizienter und innovativer Software.


Artikel teilen