logfactoryimpl.java
来自「logging日志的相关包 logging日志的相关包」· Java 代码 · 共 1,401 行 · 第 1/4 页
JAVA
1,401 行
try { String value = System.getProperty(property); if (value != null) { if (isDiagnosticsEnabled()) { logDiagnostic("[ENV] Found system property [" + value + "] for " + property); } return value; } if (isDiagnosticsEnabled()) { logDiagnostic("[ENV] No system property found for property " + property); } } catch (SecurityException e) { if (isDiagnosticsEnabled()) { logDiagnostic("[ENV] Security prevented reading system property " + property); } } if (isDiagnosticsEnabled()) { logDiagnostic("[ENV] No configuration defined for item " + property); } return null; } /** * Get the setting for the user-configurable behaviour specified by key. * If nothing has explicitly been set, then return dflt. */ private boolean getBooleanConfiguration(String key, boolean dflt) { String val = getConfigurationValue(key); if (val == null) return dflt; return Boolean.valueOf(val).booleanValue(); } /** * Initialize a number of variables that control the behaviour of this * class and that can be tweaked by the user. This is done when the first * logger is created, not in the constructor of this class, because we * need to give the user a chance to call method setAttribute in order to * configure this object. */ private void initConfiguration() { allowFlawedContext = getBooleanConfiguration(ALLOW_FLAWED_CONTEXT_PROPERTY, true); allowFlawedDiscovery = getBooleanConfiguration(ALLOW_FLAWED_DISCOVERY_PROPERTY, true); allowFlawedHierarchy = getBooleanConfiguration(ALLOW_FLAWED_HIERARCHY_PROPERTY, true); } /** * Attempts to create a Log instance for the given category name. * Follows the discovery process described in the class javadoc. * * @param logCategory the name of the log category * * @throws LogConfigurationException if an error in discovery occurs, * or if no adapter at all can be instantiated */ private Log discoverLogImplementation(String logCategory) throws LogConfigurationException { if (isDiagnosticsEnabled()) { logDiagnostic("Discovering a Log implementation..."); } initConfiguration(); Log result = null; // See if the user specified the Log implementation to use String specifiedLogClassName = findUserSpecifiedLogClassName(); if (specifiedLogClassName != null) { if (isDiagnosticsEnabled()) { logDiagnostic("Attempting to load user-specified log class '" + specifiedLogClassName + "'..."); } result = createLogFromClass(specifiedLogClassName, logCategory, true); if (result == null) { StringBuffer messageBuffer = new StringBuffer("User-specified log class '"); messageBuffer.append(specifiedLogClassName); messageBuffer.append("' cannot be found or is not useable."); // Mistyping or misspelling names is a common fault. // Construct a good error message, if we can if (specifiedLogClassName != null) { informUponSimilarName(messageBuffer, specifiedLogClassName, LOGGING_IMPL_LOG4J_LOGGER); informUponSimilarName(messageBuffer, specifiedLogClassName, LOGGING_IMPL_JDK14_LOGGER); informUponSimilarName(messageBuffer, specifiedLogClassName, LOGGING_IMPL_LUMBERJACK_LOGGER); informUponSimilarName(messageBuffer, specifiedLogClassName, LOGGING_IMPL_SIMPLE_LOGGER); } throw new LogConfigurationException(messageBuffer.toString()); } return result; } // No user specified log; try to discover what's on the classpath // // Note that we deliberately loop here over classesToDiscover and // expect method createLogFromClass to loop over the possible source // classloaders. The effect is: // for each discoverable log adapter // for each possible classloader // see if it works // // It appears reasonable at first glance to do the opposite: // for each possible classloader // for each discoverable log adapter // see if it works // // The latter certainly has advantages for user-installable logging // libraries such as log4j; in a webapp for example this code should // first check whether the user has provided any of the possible // logging libraries before looking in the parent classloader. // Unfortunately, however, Jdk14Logger will always work in jvm>=1.4, // and SimpleLog will always work in any JVM. So the loop would never // ever look for logging libraries in the parent classpath. Yet many // users would expect that putting log4j there would cause it to be // detected (and this is the historical JCL behaviour). So we go with // the first approach. A user that has bundled a specific logging lib // in a webapp should use a commons-logging.properties file or a // service file in META-INF to force use of that logging lib anyway, // rather than relying on discovery. if (isDiagnosticsEnabled()) { logDiagnostic( "No user-specified Log implementation; performing discovery" + " using the standard supported logging implementations..."); } for(int i=0; (i<classesToDiscover.length) && (result == null); ++i) { result = createLogFromClass(classesToDiscover[i], logCategory, true); } if (result == null) { throw new LogConfigurationException ("No suitable Log implementation"); } return result; } /** * Appends message if the given name is similar to the candidate. * @param messageBuffer <code>StringBuffer</code> the message should be appended to, * not null * @param name the (trimmed) name to be test against the candidate, not null * @param candidate the candidate name (not null) */ private void informUponSimilarName(final StringBuffer messageBuffer, final String name, final String candidate) { if (name.equals(candidate)) { // Don't suggest a name that is exactly the same as the one the // user tried... return; } // If the user provides a name that is in the right package, and gets // the first 5 characters of the adapter class right (ignoring case), // then suggest the candidate adapter class name. if (name.regionMatches(true, 0, candidate, 0, PKG_LEN + 5)) { messageBuffer.append(" Did you mean '"); messageBuffer.append(candidate); messageBuffer.append("'?"); } } /** * Checks system properties and the attribute map for * a Log implementation specified by the user under the * property names {@link #LOG_PROPERTY} or {@link #LOG_PROPERTY_OLD}. * * @return classname specified by the user, or <code>null</code> */ private String findUserSpecifiedLogClassName() { if (isDiagnosticsEnabled()) { logDiagnostic("Trying to get log class from attribute '" + LOG_PROPERTY + "'"); } String specifiedClass = (String) getAttribute(LOG_PROPERTY); if (specifiedClass == null) { // @deprecated if (isDiagnosticsEnabled()) { logDiagnostic("Trying to get log class from attribute '" + LOG_PROPERTY_OLD + "'"); } specifiedClass = (String) getAttribute(LOG_PROPERTY_OLD); } if (specifiedClass == null) { if (isDiagnosticsEnabled()) { logDiagnostic("Trying to get log class from system property '" + LOG_PROPERTY + "'"); } try { specifiedClass = System.getProperty(LOG_PROPERTY); } catch (SecurityException e) { if (isDiagnosticsEnabled()) { logDiagnostic("No access allowed to system property '" + LOG_PROPERTY + "' - " + e.getMessage()); } } } if (specifiedClass == null) { // @deprecated if (isDiagnosticsEnabled()) { logDiagnostic("Trying to get log class from system property '" + LOG_PROPERTY_OLD + "'"); } try { specifiedClass = System.getProperty(LOG_PROPERTY_OLD); } catch (SecurityException e) { if (isDiagnosticsEnabled()) { logDiagnostic("No access allowed to system property '" + LOG_PROPERTY_OLD + "' - " + e.getMessage()); } } } // Remove any whitespace; it's never valid in a classname so its // presence just means a user mistake. As we know what they meant, // we may as well strip the spaces. if (specifiedClass != null) { specifiedClass = specifiedClass.trim(); } return specifiedClass; } /** * Attempts to load the given class, find a suitable constructor, * and instantiate an instance of Log. * * @param logAdapterClassName classname of the Log implementation * * @param logCategory argument to pass to the Log implementation's * constructor * * @param affectState <code>true</code> if this object's state should * be affected by this method call, <code>false</code> otherwise. * * @return an instance of the given class, or null if the logging * library associated with the specified adapter is not available. * * @throws LogConfigurationException if there was a serious error with * configuration and the handleFlawedDiscovery method decided this * problem was fatal. */ private Log createLogFromClass(String logAdapterClassName, String logCategory, boolean affectState) throws LogConfigurationException { if (isDiagnosticsEnabled()) { logDiagnostic("Attempting to instantiate '" + logAdapterClassName + "'"); } Object[] params = { logCategory }; Log logAdapter = null; Constructor constructor = null; Class logAdapterClass = null; ClassLoader currentCL = getBaseClassLoader(); for(;;) { // Loop through the classloader hierarchy trying to find // a viable classloader. logDiagnostic( "Trying to load '" + logAdapterClassName + "' from classloader " + 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 classloader is doing // something weird. URL url; 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 c = null; try { c = Class.forName(logAdapterClassName, true, currentCL); } catch (ClassNotFoundException originalClassNotFoundException) { // The current classloader was unable to find the log adapter // in this or any ancestor classloader. 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 classloader " + objectId(currentCL) + ": " + msg.trim()); try { // Try the class classloader. // This may work in cases where the TCCL // does not contain the code executed or JCL. // This behaviour 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. c = Class.forName(logAdapterClassName); } catch (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 classloader: " + msg.trim()); break; } } constructor = c.getConstructor(logConstructorSignature); 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 = c; 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
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?