All,

Please check this thread for full details: https://lists.apache.org/thread/of5ozg43zyk729cg311dktjcv3swct26

Briefly, a user reported this NPE:

Apr 29, 2023 5:41:32 PM org.apache.catalina.core.StandardContext listenerStart SEVERE: Exception sending context initialized event to listener instance of class [org.springframework.web.context.ContextLoaderListener]
java.lang.NullPointerException
at org.apache.catalina.loader.WebappClassLoaderBase$CombinedEnumeration.inc(WebappClassLoaderBase.java:2775) at org.apache.catalina.loader.WebappClassLoaderBase$CombinedEnumeration.hasMoreElements(WebappClassLoaderBase.java:2760) at org.apache.commons.logging.LogFactory.getConfigurationFile(LogFactory.java:1366) at org.apache.commons.logging.LogFactory.getFactory(LogFactory.java:453)
    at org.apache.commons.logging.LogFactory.getLog(LogFactory.java:655)

Mark introduced the CombinedEnumeration in https://github.com/apache/tomcat/commit/fdd35009ead6365cbae84008e63356d6ab88ed40 to merge the resources from the parent ClassLoader with the WebappClassLoader(Base). His code looks sound to me, but it can expose what I think of as a bug in the ClassLoader being used as the parent.

ClassLoader.getResources is documented to return an empty Enumeration if there are no matching resources, but in this case, the ClassLoader is returning null.

WebappClassLoaderBase assumes that the parent ClassLoader is following the rules and so grabs the resources from both itself and the parent and combines them using CombinedEnumeration.

Here is a patch that will fix that:

diff --git a/java/org/apache/catalina/loader/WebappClassLoaderBase.java b/java/org/apache/catalina/loader/WebappClassLoaderBase.java
index aa747a5873..6f98f6e413 100644
--- a/java/org/apache/catalina/loader/WebappClassLoaderBase.java
+++ b/java/org/apache/catalina/loader/WebappClassLoaderBase.java
@@ -1121,7 +1121,9 @@ public abstract class WebappClassLoaderBase extends URLClassLoader // Enumerations are combined depends on how delegation is configured
         boolean delegateFirst = delegate || filter(name, false);

-        if (delegateFirst) {
+        if(null == parentResources) {
+            return localResources;
+        } else if (delegateFirst) {
return new CombinedEnumeration(parentResources, localResources);
         } else {
return new CombinedEnumeration(localResources, parentResources);

But my question is whether or not this is something that Tomcat should be working-around. IMO the parent ClassLoader is buggy and should be fixed, but it may be difficult or impossible to fix the parent, so it may be worth it.

We could even log it including the class name of the offending ClassLoader.

WDYT?

-chris

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org

Reply via email to