-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
NoClassDefFoundError for org.apache.logging.log4j.spi.ExtendedLogger in Tomcat 11 with Java 21 #3504
Comments
Can you clarify more what do you mean by "server classloader"? Are you talking about the parent of all web-app classloaders (see Tomcat classloading? How do you dynamically add JARs to a running classloader? Classloader are usually designed to be immutable.
Do you have a root cause for the If Some libraries, for example |
When I mentioned "server classloader," I was referring to the classloader obtained via:
We use a custom URLClassLoader reflection-based approach to dynamically load JARs at runtime. Below is the code we are using:
With this approach, we are successfully loading JARs at runtime without any immediate errors or exceptions. We have verified through debugging that the log4j-api JAR is also loaded properly into the classloader. However, despite being loaded, we still encounter The same application worked
The issue disappears after restarting the Tomcat 11 server. Once the server is restarted, everything works fine, and Log4j classes load without any errors.
Before loading the extension (which contains log4j-api), we explicitly checked whether the class
This check confirmed that the class was NOT present before loading the extension. We would appreciate any insights into why this behavior might occur in Tomcat 11 and whether Log4j's classloading mechanism has specific dependencies or behaviors that could be affected by dynamic JAR loading. |
Sorry, this statement is incorrect: classloaders don't have a negative cache of classes that don't exist. However, Tomcat introduced one in its October 2024 releases (see 9.0.97 release notes for example):
This is why your code fails on newer Tomcat releases: by calling I didn't test it, but setting <Context notFoundClassResourceCacheSize="0">
...
</Context> |
A side question: I know that upgrading is painful, especially since we had approximately one new release per month last year, but What could we do, in your opinion, to motivate users to use maintained versions of Log4j (currently only the last minor release of Note: I am using "maintenance" instead of "support", since the level of "support" for all Log4j releases is the same: we answer questions if we remember how things worked in that release (even for Log4j 1). Of course more recent releases offer better "support". 😉 |
Problem Description
Our web application, which runs in Tomcat 11 and Java 21, uses SLF4J + Logback for logging. However, it allows dynamically importing extensions along with JARs at runtime using the server classloader. One of these extensions depends on
log4j-api-2.17.1.jar
, which is correctly present in the classpath.After deploying the extension, calling a service that uses Log4j results in the following error:
java.lang.NoClassDefFoundError: org/apache/logging/log4j/spi/ExtendedLogger
The error mentioned above is being received by executing this line
Logger logger = LogManager.getLogger();
in extension service.However, other Log4j classes, such as
LogManager
andLogger
, are loading without issues.Environment Details
Application Type : WAR-based Java web application
Application Server : Apache Tomcat 11
Java Version : 21
Logging Framework in Main App : SLF4J with Logback
Extension Support : Allows dynamic loading of JARs at runtime using the server classloader
Problematic Dependency : log4j-api-2.17.1.jar (used by an extension)
Debugging Steps & Findings
log4j-api-2.17.1.jar
is present in the classpath and containsorg/apache/logging/log4j/spi/ExtendedLogger.class
.log4j-api
dependency in our application. Result : Only one instance of log4j-api-2.17.1.jar is found.Result:
LogManager
andLogger
printed correctly.ExtendedLogger.class
throwsNoClassDefFoundError
.Additional Notes
Same application worked in Tomcat 9 without requiring a restart.
Tomcat 11 requires a restart for
ExtendedLogger
to be found.After restarting Tomcat 11, everything works correctly.
Request for Help
We need guidance on :
Why is
ExtendedLogger
missing, even though other Log4j classes load fine?Does Tomcat 11’s classloader affect Log4j differently compared to Tomcat 9?
Are there additional configurations we should try in Tomcat 11?
Would appreciate any insights from the community!
The text was updated successfully, but these errors were encountered: