please take a look and check for typo's, bugs etc. 

i'm working on something for the troubleshooting documentation about
this.

- robert

On Tue, 2006-03-07 at 21:54 +0000, [EMAIL PROTECTED] wrote:
> Author: rdonkin
> Date: Tue Mar  7 13:54:57 2006
> New Revision: 384025
> 
> URL: http://svn.apache.org/viewcvs?rev=384025&view=rev
> Log:
> Improved diagnostics and added more information to the message thrown when a 
> custom LogFactory cannot be loaded due to classloader incompatibilities.
> 
> Modified:
>     
> jakarta/commons/proper/logging/trunk/src/java/org/apache/commons/logging/LogFactory.java
> 
> Modified: 
> jakarta/commons/proper/logging/trunk/src/java/org/apache/commons/logging/LogFactory.java
> URL: 
> http://svn.apache.org/viewcvs/jakarta/commons/proper/logging/trunk/src/java/org/apache/commons/logging/LogFactory.java?rev=384025&r1=384024&r2=384025&view=diff
> ==============================================================================
> --- 
> jakarta/commons/proper/logging/trunk/src/java/org/apache/commons/logging/LogFactory.java
>  (original)
> +++ 
> jakarta/commons/proper/logging/trunk/src/java/org/apache/commons/logging/LogFactory.java
>  Tue Mar  7 13:54:57 2006
> @@ -1101,13 +1101,29 @@
>                          // loading with that loader (not the TCCL). Just 
> throw an
>                          // appropriate exception here.
>  
> +                     final boolean implementsLogFactory = 
> implementsLogFactory(logFactoryClass);
> +                        
> +                        //
> +                        // Construct a good message: users may not actual 
> expect that a custom implementation 
> +                        // has been specified. Several well known containers 
> use this mechanism to adapt JCL 
> +                        // to their native logging system. 
> +                        // 
>                          String msg = 
> +                             "The application has specified that a custom 
> LogFactory implementation should be used but " +
>                              "Class '" + factoryClass + "' cannot be 
> converted to '"
> -                            + LogFactory.class.getName() + "'."
> -                            + " Perhaps you have multiple copies of 
> LogFactory in"
> -                            + " the classpath? If so, consider using the"
> -                            + " commons-logging-adapters.jar file.";
> -
> +                            + LogFactory.class.getName() + "'. ";
> +                        if (implementsLogFactory) {
> +                            msg = msg + "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. ";
> +                        } else {
> +                             msg = msg + "Please check the custom 
> implementation. ";
> +                        }
> +                        msg = msg + "Help can be found 
> @http://jakarta.apache.org/commons/logging/troubleshooting.html.";;
> +                        
>                          if (isDiagnosticsEnabled()) {
>                              logDiagnostic(msg);
>                          }
> @@ -1171,6 +1187,70 @@
>              return new LogConfigurationException(e);
>          }
>      }
> +
> +    /**
> +     * Determines whether the given class actually implements 
> <code>LogFactory</code>.
> +     * Diagnostic information is also logged.
> +     * <p>
> +     * <strong>Usage:</strong> to diagnose whether a classloader conflict is 
> the cause
> +     * of incompatibility. The test used is whether the class is assignable 
> from
> +     * the <code>LogFactory</code> class loaded by the class's classloader.
> +     * @param logFactoryClass <code>Class</code> which may implement 
> <code>LogFactory</code>
> +     * @return true if the <code>Class</code> is assignable from the 
> +     */
> +     private static boolean implementsLogFactory(Class logFactoryClass) {
> +             boolean implementsLogFactory = false;
> +             if (logFactoryClass != null) {
> +                     try {
> +                         ClassLoader logFactoryClassLoader = 
> logFactoryClass.getClassLoader();
> +                         if (logFactoryClassLoader == null) {
> +                             logDiagnostic("[CUSTOM LOG FACTORY] was loaded 
> by the boot classloader");
> +                         } else {
> +                             logHierarchy("[CUSTOM LOG FACTORY] ", 
> logFactoryClassLoader);
> +                             Class factoryFromCustomLoader 
> +                                     = 
> Class.forName("org.apache.commons.logging.LogFactory", false, 
> logFactoryClassLoader);
> +                             implementsLogFactory = 
> factoryFromCustomLoader.isAssignableFrom(logFactoryClass);
> +                             if (implementsLogFactory) {
> +                                     logDiagnostic("[CUSTOM LOG FACTORY] " + 
> logFactoryClass.getName() 
> +                                                     + " implements 
> LogFactory but was loaded by an incompatible classloader.");
> +                             } else {
> +                                     logDiagnostic("[CUSTOM LOG FACTORY] " + 
> logFactoryClass.getName() 
> +                                                     + " does not implement 
> LogFactory.");
> +                             }
> +                         }
> +                     } catch (SecurityException e) {
> +                             //
> +                             // The application is running within a hostile 
> security environment.
> +                             // This will make it very hard to diagnose 
> issues with JCL.
> +                             // Consider running less securely whilst 
> debugging this issue.
> +                             //
> +                             logDiagnostic("[CUSTOM LOG FACTORY] 
> SecurityException thrown whilst trying to determine whether " +
> +                                             "the compatibility was caused 
> by a classloader conflict: " 
> +                                             + e.getMessage());
> +                     } catch (LinkageError e) {
> +                             //
> +                             // This should be an unusual circumstance.
> +                             // LinkageError's usually indicate that a 
> dependent class has incompatibly changed.
> +                             // Another possibility may be an exception 
> thrown by an initializer.
> +                             // Time for a clean rebuild?
> +                             //
> +                             logDiagnostic("[CUSTOM LOG FACTORY] 
> LinkageError thrown whilst trying to determine whether " +
> +                                             "the compatibility was caused 
> by a classloader conflict: " 
> +                                             + e.getMessage());
> +                     } catch (ClassNotFoundException e) {
> +                             //
> +                             // LogFactory cannot be loaded by the 
> classloader which loaded the custom factory implementation.
> +                             // The custom implementation is not viable 
> until this is corrected. 
> +                             // Ensure that the JCL jar and the custom class 
> are available from the same classloader.
> +                             // Running with diagnostics on should give 
> information about the classloaders used 
> +                             // to load the custom factory.
> +                             // 
> +                             logDiagnostic("[CUSTOM LOG FACTORY] LogFactory 
> class cannot be loaded by classloader which loaded the " +
> +                                             "custom LogFactory 
> implementation. Is the custom factory in the right classloader?");
> +                     }
> +             }
> +             return implementsLogFactory;
> +     }
>  
>      /**
>       * Applets may run in an environment where accessing resources of a 
> loader is
> 
> 
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [EMAIL PROTECTED]
> For additional commands, e-mail: [EMAIL PROTECTED]
> 
> 


---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to