Dave Dority created LOGGING-192:
-----------------------------------

             Summary: NoClassDefFoundError: 
org/apache/logging/log4j/spi/LoggerAdapter when using custom classloader
                 Key: LOGGING-192
                 URL: https://issues.apache.org/jira/browse/LOGGING-192
             Project: Commons Logging
          Issue Type: Bug
    Affects Versions: 1.3.2, 1.3.1, 1.3.0
         Environment: This behavior was observed while running Adopt Open JDK 
11 and the latest version of Tomcat 9.  The behavior can be reproduced outside 
of tomcat (see attached reproduction case).
            Reporter: Dave Dority
             Fix For: 2.0, 1.3.3
         Attachments: commons-logging-classloading-issue.zip

If you have:
 * A web application running in Tomcat which contains commons-logging:1.2
 * That web application contains a custom classloader for loading a seperately 
distributed software component (whose dependencies will conflict with the 
dependencies of the web application).
 * The software component uses commons-logging:1.3.2

When the web application attempts use software component, the code 
[here|https://github.com/apache/commons-logging/blob/rel/commons-logging-1.3.2/src/main/java/org/apache/commons/logging/LogFactory.java#L918-L938]
 looks for the presence of different logging implementation classes on the 
thread context classloader's (TCCL) classpath to select an optimal 
implementation.  It seems like what is happening is that the LogFactory class 
looking for implementation class on the TCCL's classpath and the trying to load 
the selected factory from the web application's custom classloader (the loader 
for the instance of LogFactory that is running).  This is the result:


{code:java}
Exception in thread "main" java.lang.NoClassDefFoundError: 
org/apache/logging/log4j/spi/LoggerAdapter
        at java.base/java.lang.Class.forName0(Native Method)
        at java.base/java.lang.Class.forName(Class.java:315)
        at 
org.apache.commons.logging.LogFactory.createFactory(LogFactory.java:419)
        at 
org.apache.commons.logging.LogFactory.lambda$newFactory$3(LogFactory.java:1431)
        at java.base/java.security.AccessController.doPrivileged(Native Method)
        at 
org.apache.commons.logging.LogFactory.newFactory(LogFactory.java:1431)
        at org.apache.commons.logging.LogFactory.getFactory(LogFactory.java:928)
        at org.apache.commons.logging.LogFactory.getLog(LogFactory.java:987)
        at 
org.component.ClassLoadedComponent.<clinit>(ClassLoadedComponent.java:7)
        at 
java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native
 Method)
        at 
java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
        at 
java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
        at 
java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:490)
        at java.base/java.lang.Class.newInstance(Class.java:584){code}

This occurs when the web application has commons-logging:1.2 and the software 
component has commons-logging:1.3.x.  This does not occur when both are using 
version 1.2. 

Unfortunately, changing the web application's version of commons-logging is 
outside is not something I can influence.

An isolated reproduction case is attached.  It requires Java 11.  To run it:
 * Unzip it to a directory.
 * Run 
{code:java}
./gradlew reproduceIssue{code}
  



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to