logfactoryimpl.java

来自「logging日志的相关包 logging日志的相关包」· Java 代码 · 共 1,401 行 · 第 1/4 页

JAVA
1,401
字号
                // 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, c);            } catch (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 classloader. There's no point in trying higher up                // in the hierarchy in this case..                String msg = "" + e.getMessage();                logDiagnostic(                    "The log adapter '"                    + logAdapterClassName                    + "' is missing dependencies when loaded via classloader "                    + objectId(currentCL)                    + ": "                    + msg.trim());                break;            } catch (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.                String msg = "" + e.getMessage();                logDiagnostic(                    "The log adapter '"                    + logAdapterClassName                    + "' is unable to initialize itself when loaded via classloader "                    + objectId(currentCL)                    + ": "                    + msg.trim());                break;            } catch(LogConfigurationException e) {                // call to handleFlawedHierarchy above must have thrown                // a LogConfigurationException, so just throw it on                                throw e;            } catch(Throwable t) {                // handleFlawedDiscovery will determine whether this is a fatal                // problem or not. If it is fatal, then a LogConfigurationException                // will be thrown.                handleFlawedDiscovery(logAdapterClassName, currentCL, t);            }                                    if (currentCL == null) {                break;            }                        // try the parent classloader            currentCL = currentCL.getParent();        }        if ((logAdapter != null) && affectState) {            // We've succeeded, so set instance fields            this.logClassName   = logAdapterClassName;            this.logConstructor = constructor;                        // Identify the <code>setLogFactory</code> method (if there is one)            try {                this.logMethod = logAdapterClass.getMethod("setLogFactory",                                               logMethodSignature);                logDiagnostic("Found method setLogFactory(LogFactory) in '"                               + logAdapterClassName + "'");            } catch (Throwable t) {                this.logMethod = null;                logDiagnostic(                    "[INFO] '" + logAdapterClassName                     + "' from classloader " + objectId(currentCL)                    + " does not declare optional method "                    + "setLogFactory(LogFactory)");            }                        logDiagnostic(                "Log adapter '" + logAdapterClassName                 + "' from classloader " + objectId(logAdapterClass.getClassLoader())                + " has been selected for use.");        }                return logAdapter;    }            /**     * Return the classloader from which we should try to load the logging     * adapter classes.     * <p>     * This method usually returns the context classloader. However if it     * is discovered that the classloader which loaded this class is a child     * of the context classloader <i>and</i> the allowFlawedContext option     * has been set then the classloader which loaded this class is returned     * instead.     * <p>     * The only time when the classloader which loaded this class is a     * descendant (rather than the same as or an ancestor of the context     * classloader) is when an app has created custom classloaders but     * failed to correctly set the context classloader. This is a bug in     * the calling application; however we provide the option for JCL to     * simply generate a warning rather than fail outright.     *      */    private ClassLoader getBaseClassLoader() throws LogConfigurationException {        ClassLoader thisClassLoader = getClassLoader(LogFactoryImpl.class);                if (useTCCL == false) {            return thisClassLoader;        }        ClassLoader contextClassLoader = getContextClassLoader();        ClassLoader baseClassLoader = getLowestClassLoader(                contextClassLoader, thisClassLoader);                if (baseClassLoader == null) {           // The two classloaders are not part of a parent child relationship.           // In some classloading setups (e.g. JBoss with its            // UnifiedLoaderRepository) this can still work, so if user hasn't           // forbidden it, just return the contextClassLoader.           if (allowFlawedContext) {                 if (isDiagnosticsEnabled()) {                   logDiagnostic(                           "[WARNING] the context classloader is not part of a"                           + " parent-child relationship with the classloader that"                           + " loaded LogFactoryImpl.");              }              // If contextClassLoader were null, getLowestClassLoader() would              // have returned thisClassLoader.  The fact we are here means              // contextClassLoader is not null, so we can just return it.              return contextClassLoader;           }           else {            throw new LogConfigurationException(                "Bad classloader hierarchy; LogFactoryImpl was loaded via"                + " a classloader that is not related to the current context"                + " classloader.");           }                   }        if (baseClassLoader != contextClassLoader) {            // We really should just use the contextClassLoader as the starting            // point for scanning for log adapter classes. However it is expected            // that there are a number of broken systems out there which create            // custom classloaders but fail to set the context classloader so            // we handle those flawed systems anyway.            if (allowFlawedContext) {                if (isDiagnosticsEnabled()) {                    logDiagnostic(                            "Warning: the context classloader is an ancestor of the"                            + " classloader that loaded LogFactoryImpl; it should be"                            + " the same or a descendant. The application using"                            + " commons-logging should ensure the context classloader"                            + " is used correctly.");                }            } else {                throw new LogConfigurationException(                        "Bad classloader hierarchy; LogFactoryImpl was loaded via"                        + " a classloader that is not related to the current context"                        + " classloader.");             }        }                return baseClassLoader;    }    /**     * Given two related classloaders, return the one which is a child of     * the other.     * <p>     * @param c1 is a classloader (including the null classloader)     * @param c2 is a classloader (including the null classloader)     *      * @return c1 if it has c2 as an ancestor, c2 if it has c1 as an ancestor,     * and null if neither is an ancestor of the other.     */    private ClassLoader getLowestClassLoader(ClassLoader c1, ClassLoader c2) {        // TODO: use AccessController when dealing with classloaders here                if (c1 == null)            return c2;                if (c2 == null)            return c1;                ClassLoader current;        // scan c1's ancestors to find c2        current = c1;        while (current != null) {            if (current == c2)                return c1;            current = current.getParent();        }               // scan c2's ancestors to find c1        current = c2;        while (current != null) {            if (current == c1)                return c2;            current = current.getParent();        }        return null;    }    /**     * Generates an internal diagnostic logging of the discovery failure and      * then throws a <code>LogConfigurationException</code> that wraps      * the passed <code>Throwable</code>.     *      * @param logAdapterClassName is the class name of the Log implementation     * that could not be instantiated. Cannot be <code>null</code>.     *      * @param classLoader is the classloader that we were trying to load the     * logAdapterClassName from when the exception occurred.     *      * @param discoveryFlaw is the Throwable created by the classloader     *      * @throws LogConfigurationException    ALWAYS     */    private void handleFlawedDiscovery(String logAdapterClassName,                                       ClassLoader classLoader,                                       Throwable discoveryFlaw) {                if (isDiagnosticsEnabled()) {            logDiagnostic("Could not instantiate Log '"                      + logAdapterClassName + "' -- "                      + discoveryFlaw.getClass().getName() + ": "                      + discoveryFlaw.getLocalizedMessage());               }                if (!allowFlawedDiscovery) {            throw new LogConfigurationException(discoveryFlaw);        }    }        /**     * Report a problem loading the log adapter, then either return      * (if the situation is considered recoverable) or throw a     * LogConfigurationException.     *  <p>     * There are two possible reasons why we successfully loaded the      * specified log adapter class then failed to cast it to a Log object:     * <ol>     * <li>the specific class just doesn't implement the Log interface      *     (user screwed up), or     * <li> the specified class has bound to a Log class loaded by some other     *      classloader; Log@classloaderX cannot be cast to Log@classloaderY.     * </ol>     * <p>     * Here we try to figure out which case has occurred so we can give the     * user some reasonable feedback.     *      * @param badClassLoader is the classloader we loaded the problem class from,     * ie it is equivalent to badClass.getClassLoader().     *      * @param badClass is a Class object with the desired name, but which      * does not implement Log correctly.     *      * @throws LogConfigurationException when the situation     * should not be recovered from.     */    private void handleFlawedHierarchy(ClassLoader badClassLoader, Class badClass)    throws LogConfigurationException {        boolean implementsLog = false;        String logInterfaceName = Log.class.getName();        Class interfaces[] = badClass.getInterfaces();        for (int i = 0; i < interfaces.length; i++) {            if (logInterfaceName.equals(interfaces[i].getName())) {                implementsLog = true;                break;            }        }                if (implementsLog) {            // the class does implement an interface called Log, but            // it is in the wrong classloader            if (isDiagnosticsEnabled()) {                try {                    ClassLoader logInterfaceClassLoader = getClassLoader(Log.class);                    logDiagnostic(                        "Class '" + badClass.getName()                        + "' was found in classloader "                         + objectId(badClassLoader)                        + ". It is bound to a Log interface which is not"                        + " the one loaded from classloader "                        + objectId(logInterfaceClassLoader));                } catch (Throwable t) {                    logDiagnostic(                        "Error while trying to output diagnostics about"                        + " bad class '" + badClass + "'");                }            }                        if (!allowFlawedHierarchy) {                StringBuffer msg = new StringBuffer();                msg.append("Terminating logging for this context ");                msg.append("due to bad log hierarchy. ");                msg.append("You have more than one version of '");                msg.append(Log.class.getName());                msg.append("' visible.");                if (isDiagnosticsEnabled()) {                    logDiagnostic(msg.toString());                }                 throw new LogConfigurationException(msg.toString());            }                    if (isDiagnosticsEnabled()) {                StringBuffer msg = new StringBuffer();                msg.append("Warning: bad log hierarchy. ");                msg.append("You have more than one version of '");                msg.append(Log.class.getName());                msg.append("' visible.");                logDiagnostic(msg.toString());            }        } else {            // this is just a bad adapter class            if (!allowFlawedDiscovery) {                StringBuffer msg = new StringBuffer();                msg.append("Terminating logging for this context. ");                msg.append("Log class '");                msg.append(badClass.getName());                msg.append("' does not implement the Log interface.");                if (isDiagnosticsEnabled()) {                    logDiagnostic(msg.toString());                }                                throw new LogConfigurationException(msg.toString());            }            if (isDiagnosticsEnabled()) {                StringBuffer msg = new StringBuffer();                msg.append("[WARNING] Log class '");                msg.append(badClass.getName());                msg.append("' does not implement the Log interface.");                logDiagnostic(msg.toString());            }        }    }}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?