Enhanced version.sh and version.bat Output
Change Summary
This changeset enhances the output version.sh and version.bat to display comprehensive dependency and library version information that is available to tomcat for use (read: not configured in the server.xml), making it easier to verify which versions are available without the potentially costly action of grepping the logs after the fact. The update allows a single command to retrieve all the important version information a user may need without starting tomcat. The output is also an automation friendly parseable output for scripts and monitoring tools, and allows for a quick inventory of libraries that could be used by the instance.
I've added six public methods total across three classes to expose version info and reduce the need for as much reflection, introduced 14 new tests which covers all of the changes in ServerInfo, and ensured that the change is compatible with Java 8+ and ready for backporting all the way to Tomcat 9.0.x with no changes required.
Files Modified
-
bin/catalina.shandbin/catalina.bat- Updated classpath for
versioncommand to include:-
tomcat-juli.jar(for logging support) - All JARs in
$CATALINA_HOME/lib/*(for APR/FFM classes)
-
- Added
-Dcatalina.homeand-Dcatalina.basesystem properties to have access to third-party jars - Note:These changes are minimal impact as they only affects
versioncommand, not normal startup
- Updated classpath for
-
java/org/apache/catalina/core/AprLifecycleListener.java- Added minimal public API (4 methods) to expose version information, per markt's suggestion on the dev-list thread:
-
getInstalledTcnVersion()- Returns Tomcat Native version string -
getInstalledAprVersion()- Returns APR version string -
getInstalledOpenSslVersion()- Returns OpenSSL version string (via APR) -
getTcnVersionWarning()- Returns version warning if installed version is outdated
-
- Encapsulates version comparison logic internally (no need to expose individual version components)
- Added minimal public API (4 methods) to expose version information, per markt's suggestion on the dev-list thread:
-
java/org/apache/catalina/core/OpenSSLLifecycleListener.java- Added public static method
getInstalledOpenSslVersion()to expose FFM OpenSSL version - Uses reflection to call
OpenSSLLibrary.getVersionString()for native version string to avoid compile time deps
- Added public static method
-
java/org/apache/tomcat/util/net/openssl/panama/OpenSSLLibrary.java- Added public static method
getVersionString()to expose native OpenSSL version string - Ensures FFM output format matches APR format for consistency
- Added public static method
-
java/org/apache/catalina/util/ServerInfo.java- Added proactive Tomcat Native and APR initialization and version detection
- Added Tomcat Native version warning when installed version is older than recommended
- Added proactive FFM OpenSSL initialization and version detection
- Added third-party library scanning with manifest-based version extraction
- Implemented manifest-based filtering to distinguish Tomcat core JARs from third-party libraries
- Suppressed INFO logging for o.a.c.core and o.a.t.u.n.openssl.panama during initialization for clean output
- Added well formatted, aligned output for third-party libraries
- Uses public methods from listener classes instead of reflection (reduced reflection usage)
- Uses
getConstructor().newInstance()instead of Java 9+getDeclaredConstructor()for Java 8 compat
-
test/org/apache/catalina/util/TestServerInfo.java- Added 14 new tests bringing the total coverage up to 19 tests (may be a bit overkill, but good practice and it runs in 100ms or so)
- Tests for manifest-based JAR filtering (
isTomcatCoreJar()) - Tests for version extraction (
getJarVersion()) - Tests for APR detection and version output
- Tests for Tomcat Native version warning with real installed version
- Tests for FFM OpenSSL detection and version output
- Added helper method
captureServerInfoOutput()to eliminate test code duplication - Uses
Consumer<Manifest>for test JAR creation (Java 8 compatible) - Tests use
Assume.assumeTrue()to skip gracefully when native libraries unavailable
-
webapps/docs/changelog.xml- Added changelog entry documenting the enhancement
Example Output
Before:
Server version: Apache Tomcat/12.0.0-M1-dev
Server built: Oct 22 2025 17:47:46 UTC
Server number: 12.0.0.0
OS Name: Linux
OS Version: 6.17.4-200.fc42.x86_64
Architecture: amd64
JVM Version: 25+36
JVM Vendor: Red Hat, Inc.
After:
Server version: Apache Tomcat/12.0.0-M1-dev
Server built: Oct 22 2025 17:47:46 UTC
Server number: 12.0.0.0
OS Name: Linux
OS Version: 6.17.4-200.fc42.x86_64
Architecture: amd64
JVM Version: 25+36
JVM Vendor: Red Hat, Inc.
APR loaded: true
APR Version: 1.7.6
Tomcat Native: 1.3.0
WARNING: Tomcat recommends a minimum version of 2.0.5
OpenSSL (APR): OpenSSL 3.2.6 30 Sep 2025
OpenSSL (FFM): OpenSSL 3.2.6 30 Sep 2025
Third-party libraries:
ecj-4.37.jar: 3.43.0.v20250819-1513
test.jar: (unknown)
jakartaee-migration-1.0.9-shaded.jar: 1.0.9
New Information in Output
-
APR and Tomcat Native Detection (when available)
- APR loaded status
- APR version
- Tomcat Native version with version compatibility warning (displayed when installed version is older than recommended)
- OpenSSL version (via APR)
-
FFM OpenSSL Detection (when available)
- OpenSSL library name and version (via FFM API)
-
Third-Party Libraries
- Automatic detection of non-Tomcat JARs in
lib/ - Version information extracted from JAR manifests
- Shows "(unknown)" for JARs without version metadata
- Clean, aligned formatting
- Includes libraries like: ECJ compiler, JDBC drivers, migration tools, etc.
- Automatic detection of non-Tomcat JARs in
Force pushed to fix checkstyle failings since validate is off by default :(