⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 logfactory.java

📁 logging日志的相关包 logging日志的相关包
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
        return classLoader;    }    /**     * Check cached factories (keyed by contextClassLoader)     *     * @param contextClassLoader is the context classloader associated     * with the current thread. This allows separate LogFactory objects     * per component within a container, provided each component has     * a distinct context classloader set. This parameter may be null     * in JDK1.1, and in embedded systems where jcl-using code is     * placed in the bootclasspath.     *      * @return the factory associated with the specified classloader if     * one has previously been created, or null if this is the first time     * we have seen this particular classloader.     */    private static LogFactory getCachedFactory(ClassLoader contextClassLoader)    {        LogFactory factory = null;        if (contextClassLoader == null) {            // We have to handle this specially, as factories is a Hashtable            // and those don't accept null as a key value.            //            // nb: nullClassLoaderFactory might be null. That's ok.            factory = nullClassLoaderFactory;        } else {            factory = (LogFactory) factories.get(contextClassLoader);        }        return factory;    }    /**     * Remember this factory, so later calls to LogFactory.getCachedFactory     * can return the previously created object (together with all its     * cached Log objects).     *     * @param classLoader should be the current context classloader. Note that     * this can be null under some circumstances; this is ok.     *     * @param factory should be the factory to cache. This should never be null.     */    private static void cacheFactory(ClassLoader classLoader, LogFactory factory)    {        // Ideally we would assert(factory != null) here. However reporting        // errors from within a logging implementation is a little tricky!        if (factory != null) {            if (classLoader == null) {                nullClassLoaderFactory = factory;            } else {                factories.put(classLoader, factory);            }        }    }    /**     * Return a new instance of the specified <code>LogFactory</code>     * implementation class, loaded by the specified class loader.     * If that fails, try the class loader used to load this     * (abstract) LogFactory.     * <p>     * <h2>ClassLoader conflicts</h2>     * Note that there can be problems if the specified ClassLoader is not the      * same as the classloader that loaded this class, ie when loading a     * concrete LogFactory subclass via a context classloader.     * <p>     * The problem is the same one that can occur when loading a concrete Log     * subclass via a context classloader.     * <p>     * The problem occurs when code running in the context classloader calls     * class X which was loaded via a parent classloader, and class X then calls     * LogFactory.getFactory (either directly or via LogFactory.getLog). Because     * class X was loaded via the parent, it binds to LogFactory loaded via     * the parent. When the code in this method finds some LogFactoryYYYY     * class in the child (context) classloader, and there also happens to be a     * LogFactory class defined in the child classloader, then LogFactoryYYYY     * will be bound to LogFactory@childloader. It cannot be cast to     * LogFactory@parentloader, ie this method cannot return the object as     * the desired type. Note that it doesn't matter if the LogFactory class     * in the child classloader is identical to the LogFactory class in the     * parent classloader, they are not compatible.     * <p>     * The solution taken here is to simply print out an error message when     * this occurs then throw an exception. The deployer of the application     * must ensure they remove all occurrences of the LogFactory class from     * the child classloader in order to resolve the issue. Note that they     * do not have to move the custom LogFactory subclass; that is ok as     * long as the only LogFactory class it can find to bind to is in the     * parent classloader.     * <p>     * @param factoryClass Fully qualified name of the <code>LogFactory</code>     *  implementation class     * @param classLoader ClassLoader from which to load this class     * @param contextClassLoader is the context that this new factory will     * manage logging for.     *     * @exception LogConfigurationException if a suitable instance     *  cannot be created     * @since 1.1     */    protected static LogFactory newFactory(final String factoryClass,                                           final ClassLoader classLoader,                                           final ClassLoader contextClassLoader)        throws LogConfigurationException    {        // Note that any unchecked exceptions thrown by the createFactory        // method will propagate out of this method; in particular a        // ClassCastException can be thrown.        Object result = AccessController.doPrivileged(            new PrivilegedAction() {                public Object run() {                    return createFactory(factoryClass, classLoader);                }            });        if (result instanceof LogConfigurationException) {            LogConfigurationException ex = (LogConfigurationException) result;            if (isDiagnosticsEnabled()) {                logDiagnostic(                        "An error occurred while loading the factory class:"                        + ex.getMessage());            }            throw ex;        }        if (isDiagnosticsEnabled()) {            logDiagnostic(                    "Created object " + objectId(result)                    + " to manage classloader " + objectId(contextClassLoader));        }        return (LogFactory)result;    }    /**     * Method provided for backwards compatibility; see newFactory version that     * takes 3 parameters.     * <p>     * This method would only ever be called in some rather odd situation.     * Note that this method is static, so overriding in a subclass doesn't     * have any effect unless this method is called from a method in that     * subclass. However this method only makes sense to use from the     * getFactory method, and as that is almost always invoked via     * LogFactory.getFactory, any custom definition in a subclass would be     * pointless. Only a class with a custom getFactory method, then invoked     * directly via CustomFactoryImpl.getFactory or similar would ever call     * this. Anyway, it's here just in case, though the "managed class loader"     * value output to the diagnostics will not report the correct value.     */    protected static LogFactory newFactory(final String factoryClass,                                           final ClassLoader classLoader) {	    return newFactory(factoryClass, classLoader, null);    }    /**     * Implements the operations described in the javadoc for newFactory.     *      * @param factoryClass     *      * @param classLoader used to load the specified factory class. This is     * expected to be either the TCCL or the classloader which loaded this     * class. Note that the classloader which loaded this class might be     * "null" (ie the bootloader) for embedded systems.     *      * @return either a LogFactory object or a LogConfigurationException object.     * @since 1.1     */    protected static Object createFactory(String factoryClass, ClassLoader classLoader) {        // This will be used to diagnose bad configurations        // and allow a useful message to be sent to the user        Class logFactoryClass = null;        try {            if (classLoader != null) {                try {                    // First the given class loader param (thread class loader)                    // Warning: must typecast here & allow exception                    // to be generated/caught & recast properly.                    logFactoryClass = classLoader.loadClass(factoryClass);                    if (LogFactory.class.isAssignableFrom(logFactoryClass)) {                        if (isDiagnosticsEnabled()) {                            logDiagnostic(                                    "Loaded class " + logFactoryClass.getName()                                    + " from classloader " + objectId(classLoader));                        }                    } else {                        //                        // This indicates a problem with the ClassLoader tree.                        // An incompatible ClassLoader was used to load the                         // implementation.                         // As the same classes                        // must be available in multiple class loaders,                        // it is very likely that multiple JCL jars are present.                        // The most likely fix for this                        // problem is to remove the extra JCL jars from the                         // ClassLoader hierarchy.                         //                        if (isDiagnosticsEnabled()) {                            logDiagnostic(                                    "Factory class " + logFactoryClass.getName()                                + " loaded from classloader " + objectId(logFactoryClass.getClassLoader())                                + " does not extend '" + LogFactory.class.getName()                                + "' as loaded by this classloader.");                            logHierarchy("[BAD CL TREE] ", classLoader);                        }                    }                                        return (LogFactory) logFactoryClass.newInstance();                } catch (ClassNotFoundException ex) {                    if (classLoader == thisClassLoader) {                        // Nothing more to try, onwards.                        if (isDiagnosticsEnabled()) {                            logDiagnostic(                                    "Unable to locate any class called '" + factoryClass                                    + "' via classloader " + objectId(classLoader));                        }                        throw ex;                    }                    // ignore exception, continue                } catch (NoClassDefFoundError e) {                    if (classLoader == thisClassLoader) {                        // Nothing more to try, onwards.                        if (isDiagnosticsEnabled()) {                            logDiagnostic(                                    "Class '" + factoryClass + "' cannot be loaded"                                    + " via classloader " + objectId(classLoader)                                    + " - it depends on some other class that cannot"                                    + " be found.");                        }                        throw e;                    }                    // ignore exception, continue                } catch(ClassCastException e) {                    if (classLoader == thisClassLoader) {                        // There's no point in falling through to the code below that                        // tries again with thisClassLoader, because we've just tried                        // 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() + "'. ";                        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);                        }                                                ClassCastException ex = new ClassCastException(msg);                        throw ex;                    }                                        // Ignore exception, continue. Presumably the classloader was the                    // TCCL; the code below will try to load the class via thisClassLoader.                    // This will handle the case where the original calling class is in                    // a shared classpath but the TCCL has a copy of LogFactory and the                    // specified LogFactory implementation; we will fall back to using the                    // LogFactory implementation from the same classloader as this class.                    //                    // Issue: this doesn't handle the reverse case, where this LogFactory                    // is in the webapp, and the specified LogFactory implementation is                    // in a shared classpath. In that case:                    // (a) the class really does implement LogFactory (bad log msg above)                    // (b) the fallback code will result in exactly the same problem.                }            }            /* At this point, either classLoader == null, OR             * classLoader was unable to load factoryClass.             *             * In either case, we call Class.forName, which is equivalent             * to LogFactory.class.getClassLoader().load(name), ie we ignore

⌨️ 快捷键说明

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