[
https://issues.apache.org/jira/browse/LOGGING-192?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17873587#comment-17873587
]
Piotr Karwasz commented on LOGGING-192:
---------------------------------------
{quote}
Unless there are situations where the log4j log factory cannot be loaded on web,
but one of the others can be loaded on web, i.e. it does not fail because
commons-logging is missing,
I'd say it is just wasted time and should be
{quote}
Good point if {{LogFactory.class}} in _web_ is not the same class as
{{LogFactory.class}} in _custom_, there is no point to use the TCCL at all.
However if the classes are equal, I would check all factories in _web_ and then
in _custom_. The legacy factory basically can never fail (it will almost always
detect at least JUL), so in your case this procedure will use JUL instead of
the SLF4J implementation. I think this should be OK, since there is a system
property to disable the use of TCCL.
> 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.0, 1.3.1, 1.3.2
> 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
> Priority: Major
> 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)