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.xmlwith "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.jarsToScanjars 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 ?