The library I'm maintaining contains a implementation of ServletContainerInitializer
which is declared in META-INF/services/javax.servlet.ServletContainerInitializer
file.
This library is used by web applications running on Tomee 8 (Apache Tomcat (TomEE)/9.0.63 (8.0.12)).
Recently I added the log4j-web
dependency to the project. Before that my initializer was called as expected but since it is ignored.
After creating a minimal example I identified that my jar is ignored because :
- Its name starts with
spring-
(it is not a library of the Spring Framework, only a poor naming choice) and, - Another jar in the classpath (log4j-web) contains a
web-fragment.xml
with "ordering" before or after "others" :
<web-fragment xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-fragment_3_0.xsd"
version="3.0" metadata-complete="true">
<name>my_web_fragment_xxx</name>
<distributable />
<ordering>
<before>
<others />
</before>
</ordering>
</web-fragment>
I activated Tomcat traces logs and noticed that "spring" is listed in some exclusion prefixes as well as many other names.
TRACE [Thread-2] org.apache.openejb.config.NewLoaderLogic.readDefaultExclusions Loaded default.exclusions
TRACE [Thread-2] org.apache.openejb.config.NewLoaderLogic.logExclusions Exclusion prefixes: [
...
TRACE [Thread-2] org.apache.openejb.config.NewLoaderLogic.logExclusions -snappy-java-
TRACE [Thread-2] org.apache.openejb.config.NewLoaderLogic.logExclusions -spring-
TRACE [Thread-2] org.apache.openejb.config.NewLoaderLogic.logExclusions -sshd-
...
I noticed that "google" is listed too and when I prefix my jar with "google-" it reproduces the same issue.
The default exclusion list comes from openejb-core
library :
https://github.com/apache/tomee/blob/c0928e2aed1713d16d28bffaed11ad5024bc3728/container/openejb-core/src/main/resources/default.exclusions
Workarounds
- Rename the library (but it will have an impact on applications depending on it),
- Add the name of the ignored jar to the
tomcat.util.scan.StandardJarScanFilter.jarsToScan
jars list (but it has to be done to every environments from dev to production for customers using our products).
Question
What I would like to understand is, why this issue is only triggered when a jar in the classpath contains a web-fragment with an <ordering>
element ?