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]