private Log createLogFromClass()

in src/main/java/org/apache/commons/logging/impl/LogFactoryImpl.java [323:481]


    private Log createLogFromClass(final String logAdapterClassName,
                                   final String logCategory,
                                   final boolean affectState)
        throws LogConfigurationException {

        if (isDiagnosticsEnabled()) {
            logDiagnostic("Attempting to instantiate '" + logAdapterClassName + "'");
        }

        final Object[] params = { logCategory };
        Log logAdapter = null;
        Constructor<?> constructor = null;

        Class<?> logAdapterClass = null;
        ClassLoader currentCL = getBaseClassLoader();

        for(;;) {
            // Loop through the class loader hierarchy trying to find
            // a viable class loader.
            logDiagnostic("Trying to load '" + logAdapterClassName + "' from class loader " + objectId(currentCL));
            try {
                if (isDiagnosticsEnabled()) {
                    // Show the location of the first occurrence of the .class file
                    // in the classpath. This is the location that ClassLoader.loadClass
                    // will load the class from -- unless the class loader is doing
                    // something weird.
                    URL url;
                    final String resourceName = logAdapterClassName.replace('.', '/') + ".class";
                    if (currentCL != null) {
                        url = currentCL.getResource(resourceName );
                    } else {
                        url = ClassLoader.getSystemResource(resourceName + ".class");
                    }

                    if (url == null) {
                        logDiagnostic("Class '" + logAdapterClassName + "' [" + resourceName + "] cannot be found.");
                    } else {
                        logDiagnostic("Class '" + logAdapterClassName + "' was found at '" + url + "'");
                    }
                }

                Class<?> clazz;
                try {
                    clazz = Class.forName(logAdapterClassName, true, currentCL);
                } catch (final ClassNotFoundException originalClassNotFoundException) {
                    // The current class loader was unable to find the log adapter
                    // in this or any ancestor class loader. There's no point in
                    // trying higher up in the hierarchy in this case.
                    String msg = originalClassNotFoundException.getMessage();
                    logDiagnostic("The log adapter '" + logAdapterClassName + "' is not available via class loader " +
                                  objectId(currentCL) + ": " + trim(msg));
                    try {
                        // Try the class class loader.
                        // This may work in cases where the TCCL
                        // does not contain the code executed or JCL.
                        // This behavior indicates that the application
                        // classloading strategy is not consistent with the
                        // Java 1.2 classloading guidelines but JCL can
                        // and so should handle this case.
                        clazz = Class.forName(logAdapterClassName);
                    } catch (final ClassNotFoundException secondaryClassNotFoundException) {
                        // no point continuing: this adapter isn't available
                        msg = secondaryClassNotFoundException.getMessage();
                        logDiagnostic("The log adapter '" + logAdapterClassName +
                                      "' is not available via the LogFactoryImpl class class loader: " + trim(msg));
                        break;
                    }
                }

                constructor = clazz.getConstructor(logConstructorSignature);
                final Object o = constructor.newInstance(params);

                // Note that we do this test after trying to create an instance
                // [rather than testing Log.class.isAssignableFrom(c)] so that
                // we don't complain about Log hierarchy problems when the
                // adapter couldn't be instantiated anyway.
                if (o instanceof Log) {
                    logAdapterClass = clazz;
                    logAdapter = (Log) o;
                    break;
                }

                // Oops, we have a potential problem here. An adapter class
                // has been found and its underlying lib is present too, but
                // there are multiple Log interface classes available making it
                // impossible to cast to the type the caller wanted. We
                // certainly can't use this logger, but we need to know whether
                // to keep on discovering or terminate now.
                //
                // The handleFlawedHierarchy method will throw
                // LogConfigurationException if it regards this problem as
                // fatal, and just return if not.
                handleFlawedHierarchy(currentCL, clazz);
            } catch (final NoClassDefFoundError e) {
                // We were able to load the adapter but it had references to
                // other classes that could not be found. This simply means that
                // the underlying logger library is not present in this or any
                // ancestor class loader. There's no point in trying higher up
                // in the hierarchy in this case.
                final String msg = e.getMessage();
                logDiagnostic("The log adapter '" + logAdapterClassName +
                              "' is missing dependencies when loaded via class loader " + objectId(currentCL) +
                              ": " + trim(msg));
                break;
            } catch (final ExceptionInInitializerError e) {
                // A static initializer block or the initializer code associated
                // with a static variable on the log adapter class has thrown
                // an exception.
                //
                // We treat this as meaning the adapter's underlying logging
                // library could not be found.
                final String msg = e.getMessage();
                logDiagnostic("The log adapter '" + logAdapterClassName +
                              "' is unable to initialize itself when loaded via class loader " + objectId(currentCL) +
                              ": " + trim(msg));
                break;
            } catch (final LogConfigurationException e) {
                // call to handleFlawedHierarchy above must have thrown
                // a LogConfigurationException, so just throw it on
                throw e;
            } catch (final Throwable t) {
                handleThrowable(t); // may re-throw t
                // handleFlawedDiscovery will determine whether this is a fatal
                // problem or not. If it is fatal, then a LogConfigurationException
                // will be thrown.
                handleFlawedDiscovery(logAdapterClassName, t);
            }

            if (currentCL == null) {
                break;
            }

            // try the parent class loader
            // currentCL = currentCL.getParent();
            currentCL = getParentClassLoader(currentCL);
        }

        if (logAdapterClass != null && affectState) {
            // We've succeeded, so set instance fields
            this.logClassName   = logAdapterClassName;
            this.logConstructor = constructor;

            // Identify the {@code setLogFactory} method (if there is one)
            try {
                this.logMethod = logAdapterClass.getMethod("setLogFactory", logMethodSignature);
                logDiagnostic("Found method setLogFactory(LogFactory) in '" + logAdapterClassName + "'");
            } catch (final Throwable t) {
                handleThrowable(t); // may re-throw t
                this.logMethod = null;
                logDiagnostic("[INFO] '" + logAdapterClassName + "' from class loader " + objectId(currentCL) +
                              " does not declare optional method " + "setLogFactory(LogFactory)");
            }

            logDiagnostic("Log adapter '" + logAdapterClassName + "' from class loader " +
                          objectId(logAdapterClass.getClassLoader()) + " has been selected for use.");
        }

        return logAdapter;
    }