📄 logfactory.java
字号:
* the classloader parameter the caller passed, and fall back * to trying the classloader associated with this class. See the * javadoc for the newFactory method for more info on the * consequences of this. * * Notes: * * LogFactory.class.getClassLoader() may return 'null' * if LogFactory is loaded by the bootstrap classloader. */ // Warning: must typecast here & allow exception // to be generated/caught & recast properly. if (isDiagnosticsEnabled()) { logDiagnostic( "Unable to load factory class via classloader " + objectId(classLoader) + " - trying the classloader associated with this LogFactory."); } logFactoryClass = Class.forName(factoryClass); return (LogFactory) logFactoryClass.newInstance(); } catch (Exception e) { // Check to see if we've got a bad configuration if (isDiagnosticsEnabled()) { logDiagnostic("Unable to create LogFactory instance."); } if (logFactoryClass != null && !LogFactory.class.isAssignableFrom(logFactoryClass)) { return new LogConfigurationException( "The chosen LogFactory implementation does not extend LogFactory." + " Please check your configuration.", e); } 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>logFactoryClass</code> does extend * <code>LogFactory</code> when that class is loaded via the same * classloader that loaded the <code>logFactoryClass</code>. */ 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 * a secure operation, but where the commons-logging library has explicitly * been granted permission for that operation. In this case, we need to * run the operation using an AccessController. */ private static InputStream getResourceAsStream(final ClassLoader loader, final String name) { return (InputStream)AccessController.doPrivileged( new PrivilegedAction() { public Object run() { if (loader != null) { return loader.getResourceAsStream(name); } else { return ClassLoader.getSystemResourceAsStream(name); } } }); } /** * Given a filename, return an enumeration of URLs pointing to * all the occurrences of that filename in the classpath. * <p> * This is just like ClassLoader.getResources except that the * operation is done under an AccessController so that this method will * succeed when this jarfile is privileged but the caller is not. * This method must therefore remain private to avoid security issues. * <p> * If no instances are found, an Enumeration is returned whose * hasMoreElements method returns false (ie an "empty" enumeration). * If resources could not be listed for some reason, null is returned. */ private static Enumeration getResources(final ClassLoader loader, final String name) { PrivilegedAction action = new PrivilegedAction() { public Object run() { try { if (loader != null) { return loader.getResources(name); } else { return ClassLoader.getSystemResources(name); } } catch(IOException e) { if (isDiagnosticsEnabled()) { logDiagnostic( "Exception while trying to find configuration file " + name + ":" + e.getMessage()); } return null; } catch(NoSuchMethodError e) { // we must be running on a 1.1 JVM which doesn't support // ClassLoader.getSystemResources; just return null in // this case. return null; } } }; Object result = AccessController.doPrivileged(action); return (Enumeration) result; } /** * Given a URL that refers to a .properties file, load that file. * This is done under an AccessController so that this method will * succeed when this jarfile is privileged but the caller is not. * This method must therefore remain private to avoid security issues. * <p> * Null is returned if the URL cannot be opened. */ private static Properties getProperties(final URL url) { PrivilegedAction action = new PrivilegedAction() { public Object run() { try { InputStream stream = url.openStream(); if (stream != null) { Properties props = new Properties(); props.load(stream); stream.close(); return props; } } catch(IOException e) { if (isDiagnosticsEnabled()) { logDiagnostic("Unable to read URL " + url); } } return null; } }; return (Properties) AccessController.doPrivileged(action); } /** * Locate a user-provided configuration file. * <p> * The classpath of the specified classLoader (usually the context classloader) * is searched for properties files of the specified name. If none is found, * null is returned. If more than one is found, then the file with the greatest * value for its PRIORITY property is returned. If multiple files have the * same PRIORITY value then the first in the classpath is returned. * <p> * This differs from the 1.0.x releases; those always use the first one found. * However as the priority is a new field, this change is backwards compatible. * <p> * The purpose of the priority field is to allow a webserver administrator to * override logging settings in all webapps by placing a commons-logging.properties * file in a shared classpath location with a priority > 0; this overrides any * commons-logging.properties files without priorities which are in the * webapps. Webapps can also use explicit priorities to override a configuration * file in the shared classpath if needed. */ private static final Properties getConfigurationFile( ClassLoader classLoader, String fileName) { Properties props = null; double priority = 0.0; URL propsUrl = null; try { Enumeration urls = getResources(classLoader, fileName); if (urls == null) { return null; } while (urls.hasMoreElements()) { URL url = (URL) urls.nextElement(); Properties newProps = getProperties(url); if (newProps != null) { if (props == null) { propsUrl = url; props = newProps; String priorityStr = props.getProperty(PRIORITY_KEY); priority = 0.0; if (priorityStr != null) { priority = Double.parseDouble(priorityStr); } if (isDiagnosticsEnabled()) { logDiagnostic( "[LOOKUP] Properties file found at '" + url + "'" + " with priority " + priority); } } else { String newPriorityStr = newProps.getProperty(PRIORITY_KEY); double newPriority = 0.0; if (newPriorityStr != null) { newPriority = Double.parseDouble(newPriorityStr); } if (newPriority > priority) { if (isDiagnosticsEnabled()) { logDiagnostic( "[LOOKUP] Properties file at '" + url + "'" + " with priority " + newPriority + " overrides file at '" + propsUrl + "'" + " with priority " + priority); } propsUrl = url; props = newProps; priority = newPriority; } else { if (isDiagnosticsEnabled()) { logDiagnostic( "[LOOKUP] Properties file at '" + url + "'" + " with priority " + newPriority + " does not override file at '" + propsUrl + "'" + " with priority " + priority); } } } } } } catch (SecurityException e) { if (isDiagnosticsEnabled()) { logDiagnostic("SecurityException thrown while trying to find/read config files."); } } if (isDiagnosticsEnabled()) { if (props == null) { logDiagnostic( "[LOOKUP] No properties file of name '" + fileNam
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -