From 1b10d09a00a6080505b276493e2367f91c820ba1 Mon Sep 17 00:00:00 2001 From: Robert Burrell Donkin Date: Thu, 9 Mar 2006 20:21:28 +0000 Subject: [PATCH] First draft on troubleshooting WAS (and other containers that use custom LogFactory implementations). git-svn-id: https://svn.apache.org/repos/asf/jakarta/commons/proper/logging/trunk@384600 13f79535-47bb-0310-9956-ffa450edef68 --- xdocs/troubleshooting.xml | 104 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 104 insertions(+) diff --git a/xdocs/troubleshooting.xml b/xdocs/troubleshooting.xml index ddb2dde..fd4a161 100644 --- a/xdocs/troubleshooting.xml +++ b/xdocs/troubleshooting.xml @@ -207,5 +207,109 @@ classloader used to load LogFactory and to the TCCL.

+
+

+ Some containers use a custom LogFactory implementation to adapt JCL to their particular + logging system. This has some important consequences for deploying applications using JCL within these + containers. +

+

+ Containers known to use this mechanism: +

+ +

+ Containers suspected to use this mechanism: +

+ + + +

+ An exception is thrown by JCL with a message similar to: +

+
+  The chosen LogFactory implementation does not extend LogFactory. Please check your configuration. 
+  (Caused by java.lang.ClassCastException: The application has specified that a custom LogFactory 
+  implementation should be used but Class 'com.ibm.ws.commons.logging.TrLogFactory' cannot be converted 
+  to 'org.apache.commons.logging.LogFactory'. The conflict is caused by the presence of multiple 
+  LogFactory classes in incompatible classloaders. Background can be found in 
+  http://jakarta.apache.org/commons/logging/tech.html. If you have not explicitly specified a custom 
+  LogFactory then it is likely that the container has set one without your knowledge. 
+  In this case, consider using the commons-logging-adapters.jar file or specifying the standard 
+  LogFactory from the command line. Help can be found @http://jakarta.apache.org/commons/logging.
+  
+

+ This is a WebSphere example so the name of the custom LogFactory is + com.ibm.ws.commons.logging.TrLogFactory. For other containers, this class name will + differ. +

+
+ +

+ A custom LogFactory implementation can only be used if the implementation class loaded + dynamically at runtime can be cast to the LogFactory class that loaded it. There are + several ways in which this cast can fail. The most obvious is that the source code may not actually + extend LogFactory. The source may be compatible but if the LogFactory class + against which the source is compiled is not binary compatible then the cast will also fail. +

+

+ There is also another more unusual way in which this cast can fail: even when the binary is compatible, + the implementation class loaded at runtime may be linked to a different instance of the + LogFactory class. For more information, see the tech guide. +

+

+ This situation may be encountered in containers which use a custom LogFactory implementation. + The implementation will typically be provided in a shared, high level classloader together with JCL. + When an application classloader contains LogFactory, the implementation will be loaded + from that higher level classloader. The implementation class will be linked to the LogFactory + class loaded by the higher level classloader. Even if the + LogFactory implementations are binary compatible, since they are loaded by different classloaders + the two LogFactory Class instances are not equal and so the cast must fail. +

+

+The policy adopted by JCL in this situation is to re-throw this exception. Addition information +is included in the message to help diagnosis. The reasoning behind this choice is that a +particular LogFactory implementation has been actively specified and this +choice should not be ignored. This policy has unfortunate consequences when running in +containers which have custom implementations: the above runtime exception will be thrown. +

+
+ +

+ There are various ways to fix this problem. Which fix is right depends on the circumstances. +

+

+ If you want to bypass the container adaption mechanism then set the appropriate system property + to it's default value when the container is started: +

+
+ -Dorg.apache.commons.logging.LogFactory=org.apache.commons.logging.impl.LogFactoryImpl
+ 
+

+ If you want to continue to use the default container mechanism then: +

+
    +
  • + Find and replace the commons-logging implementation used by the container with + the most modern release +
  • +
  • + Replace the commons-logging jar in the application with the commons-logging-adapter jar. + This will ensure that application classloader will delegate to it's parent when loading + LogFactory. +
  • +
+

+ If you encounter difficulties when applying the fixes recommended, please turn on + diagnostics and consult the logs. +

+
+
+