diff --git a/java/lib/commons-logging-1.1.1.jar b/java/lib/commons-logging-1.1.1.jar new file mode 100644 index 0000000..8758a96 Binary files /dev/null and b/java/lib/commons-logging-1.1.1.jar differ diff --git a/java/lib/commons-logging-adapters-1.1.1.jar b/java/lib/commons-logging-adapters-1.1.1.jar new file mode 100644 index 0000000..2f23c35 Binary files /dev/null and b/java/lib/commons-logging-adapters-1.1.1.jar differ diff --git a/java/lib/commons-logging-api-1.1.1.jar b/java/lib/commons-logging-api-1.1.1.jar new file mode 100644 index 0000000..bd45116 Binary files /dev/null and b/java/lib/commons-logging-api-1.1.1.jar differ diff --git a/java/src/org/apache/commons/logging/Log.java b/java/src/org/apache/commons/logging/Log.java deleted file mode 100644 index bf80bad..0000000 --- a/java/src/org/apache/commons/logging/Log.java +++ /dev/null @@ -1,246 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - - -package org.apache.commons.logging; - -/** - *

A simple logging interface abstracting logging APIs. In order to be - * instantiated successfully by {@link LogFactory}, classes that implement - * this interface must have a constructor that takes a single String - * parameter representing the "name" of this Log.

- * - *

The six logging levels used by Log are (in order): - *

    - *
  1. trace (the least serious)
  2. - *
  3. debug
  4. - *
  5. info
  6. - *
  7. warn
  8. - *
  9. error
  10. - *
  11. fatal (the most serious)
  12. - *
- * The mapping of these log levels to the concepts used by the underlying - * logging system is implementation dependent. - * The implemention should ensure, though, that this ordering behaves - * as expected.

- * - *

Performance is often a logging concern. - * By examining the appropriate property, - * a component can avoid expensive operations (producing information - * to be logged).

- * - *

For example, - *

- *    if (log.isDebugEnabled()) {
- *        ... do something expensive ...
- *        log.debug(theResult);
- *    }
- * 
- *

- * - *

Configuration of the underlying logging system will generally be done - * external to the Logging APIs, through whatever mechanism is supported by - * that system.

- * - * @author Scott Sanders - * @author Rod Waldhoff - * @version $Id: Log.java 424107 2006-07-20 23:15:42Z skitching $ - */ -public interface Log { - - - // ----------------------------------------------------- Logging Properties - - - /** - *

Is debug logging currently enabled?

- * - *

Call this method to prevent having to perform expensive operations - * (for example, String concatenation) - * when the log level is more than debug.

- * - * @return true if debug is enabled in the underlying logger. - */ - public boolean isDebugEnabled(); - - - /** - *

Is error logging currently enabled?

- * - *

Call this method to prevent having to perform expensive operations - * (for example, String concatenation) - * when the log level is more than error.

- * - * @return true if error is enabled in the underlying logger. - */ - public boolean isErrorEnabled(); - - - /** - *

Is fatal logging currently enabled?

- * - *

Call this method to prevent having to perform expensive operations - * (for example, String concatenation) - * when the log level is more than fatal.

- * - * @return true if fatal is enabled in the underlying logger. - */ - public boolean isFatalEnabled(); - - - /** - *

Is info logging currently enabled?

- * - *

Call this method to prevent having to perform expensive operations - * (for example, String concatenation) - * when the log level is more than info.

- * - * @return true if info is enabled in the underlying logger. - */ - public boolean isInfoEnabled(); - - - /** - *

Is trace logging currently enabled?

- * - *

Call this method to prevent having to perform expensive operations - * (for example, String concatenation) - * when the log level is more than trace.

- * - * @return true if trace is enabled in the underlying logger. - */ - public boolean isTraceEnabled(); - - - /** - *

Is warn logging currently enabled?

- * - *

Call this method to prevent having to perform expensive operations - * (for example, String concatenation) - * when the log level is more than warn.

- * - * @return true if warn is enabled in the underlying logger. - */ - public boolean isWarnEnabled(); - - - // -------------------------------------------------------- Logging Methods - - - /** - *

Log a message with trace log level.

- * - * @param message log this message - */ - public void trace(Object message); - - - /** - *

Log an error with trace log level.

- * - * @param message log this message - * @param t log this cause - */ - public void trace(Object message, Throwable t); - - - /** - *

Log a message with debug log level.

- * - * @param message log this message - */ - public void debug(Object message); - - - /** - *

Log an error with debug log level.

- * - * @param message log this message - * @param t log this cause - */ - public void debug(Object message, Throwable t); - - - /** - *

Log a message with info log level.

- * - * @param message log this message - */ - public void info(Object message); - - - /** - *

Log an error with info log level.

- * - * @param message log this message - * @param t log this cause - */ - public void info(Object message, Throwable t); - - - /** - *

Log a message with warn log level.

- * - * @param message log this message - */ - public void warn(Object message); - - - /** - *

Log an error with warn log level.

- * - * @param message log this message - * @param t log this cause - */ - public void warn(Object message, Throwable t); - - - /** - *

Log a message with error log level.

- * - * @param message log this message - */ - public void error(Object message); - - - /** - *

Log an error with error log level.

- * - * @param message log this message - * @param t log this cause - */ - public void error(Object message, Throwable t); - - - /** - *

Log a message with fatal log level.

- * - * @param message log this message - */ - public void fatal(Object message); - - - /** - *

Log an error with fatal log level.

- * - * @param message log this message - * @param t log this cause - */ - public void fatal(Object message, Throwable t); - - -} diff --git a/java/src/org/apache/commons/logging/LogConfigurationException.java b/java/src/org/apache/commons/logging/LogConfigurationException.java deleted file mode 100644 index aae0708..0000000 --- a/java/src/org/apache/commons/logging/LogConfigurationException.java +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.commons.logging; - - -/** - *

An exception that is thrown only if a suitable LogFactory - * or Log instance cannot be created by the corresponding - * factory methods.

- * - * @author Craig R. McClanahan - * @version $Revision: 424107 $ $Date: 2006-07-21 01:15:42 +0200 (fr, 21 jul 2006) $ - */ - -public class LogConfigurationException extends RuntimeException { - - - /** - * Construct a new exception with null as its detail message. - */ - public LogConfigurationException() { - - super(); - - } - - - /** - * Construct a new exception with the specified detail message. - * - * @param message The detail message - */ - public LogConfigurationException(String message) { - - super(message); - - } - - - /** - * Construct a new exception with the specified cause and a derived - * detail message. - * - * @param cause The underlying cause - */ - public LogConfigurationException(Throwable cause) { - - this((cause == null) ? null : cause.toString(), cause); - - } - - - /** - * Construct a new exception with the specified detail message and cause. - * - * @param message The detail message - * @param cause The underlying cause - */ - public LogConfigurationException(String message, Throwable cause) { - - super(message + " (Caused by " + cause + ")"); - this.cause = cause; // Two-argument version requires JDK 1.4 or later - - } - - - /** - * The underlying cause of this exception. - */ - protected Throwable cause = null; - - - /** - * Return the underlying cause of this exception (if any). - */ - public Throwable getCause() { - - return (this.cause); - - } - - -} diff --git a/java/src/org/apache/commons/logging/LogFactory.java b/java/src/org/apache/commons/logging/LogFactory.java deleted file mode 100644 index f8b8955..0000000 --- a/java/src/org/apache/commons/logging/LogFactory.java +++ /dev/null @@ -1,1824 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.commons.logging; - - -import java.io.BufferedReader; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.PrintStream; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.net.URL; -import java.security.AccessController; -import java.security.PrivilegedAction; -import java.util.Enumeration; -import java.util.Hashtable; -import java.util.Properties; - - -/** - *

Factory for creating {@link Log} instances, with discovery and - * configuration features similar to that employed by standard Java APIs - * such as JAXP.

- * - *

IMPLEMENTATION NOTE - This implementation is heavily - * based on the SAXParserFactory and DocumentBuilderFactory implementations - * (corresponding to the JAXP pluggability APIs) found in Apache Xerces.

- * - * @author Craig R. McClanahan - * @author Costin Manolache - * @author Richard A. Sitze - * @version $Revision: 593798 $ $Date: 2007-11-10 18:40:43 +0100 $ - */ - -public abstract class LogFactory { - // Implementation note re AccessController usage - // - // It is important to keep code invoked via an AccessController to small - // auditable blocks. Such code must carefully evaluate all user input - // (parameters, system properties, config file contents, etc). As an - // example, a Log implementation should not write to its logfile - // with an AccessController anywhere in the call stack, otherwise an - // insecure application could configure the log implementation to write - // to a protected file using the privileges granted to JCL rather than - // to the calling application. - // - // Under no circumstance should a non-private method return data that is - // retrieved via an AccessController. That would allow an insecure app - // to invoke that method and obtain data that it is not permitted to have. - // - // Invoking user-supplied code with an AccessController set is not a major - // issue (eg invoking the constructor of the class specified by - // HASHTABLE_IMPLEMENTATION_PROPERTY). That class will be in a different - // trust domain, and therefore must have permissions to do whatever it - // is trying to do regardless of the permissions granted to JCL. There is - // a slight issue in that untrusted code may point that environment var - // to another trusted library, in which case the code runs if both that - // lib and JCL have the necessary permissions even when the untrusted - // caller does not. That's a pretty hard route to exploit though. - - - // ----------------------------------------------------- Manifest Constants - - /** - * The name (priority) of the key in the config file used to - * specify the priority of that particular config file. The associated value - * is a floating-point number; higher values take priority over lower values. - */ - public static final String PRIORITY_KEY = "priority"; - - /** - * The name (use_tccl) of the key in the config file used - * to specify whether logging classes should be loaded via the thread - * context class loader (TCCL), or not. By default, the TCCL is used. - */ - public static final String TCCL_KEY = "use_tccl"; - - /** - * The name (org.apache.commons.logging.LogFactory) of the property - * used to identify the LogFactory implementation - * class name. This can be used as a system property, or as an entry in a - * configuration properties file. - */ - public static final String FACTORY_PROPERTY = - "org.apache.commons.logging.LogFactory"; - - /** - * The fully qualified class name of the fallback LogFactory - * implementation class to use, if no other can be found. - */ - public static final String FACTORY_DEFAULT = - "org.apache.commons.logging.impl.LogFactoryImpl"; - - /** - * The name (commons-logging.properties) of the properties file to search for. - */ - public static final String FACTORY_PROPERTIES = - "commons-logging.properties"; - - /** - * JDK1.3+ - * 'Service Provider' specification. - * - */ - protected static final String SERVICE_ID = - "META-INF/services/org.apache.commons.logging.LogFactory"; - - /** - * The name (org.apache.commons.logging.diagnostics.dest) - * of the property used to enable internal commons-logging - * diagnostic output, in order to get information on what logging - * implementations are being discovered, what classloaders they - * are loaded through, etc. - *

- * If a system property of this name is set then the value is - * assumed to be the name of a file. The special strings - * STDOUT or STDERR (case-sensitive) indicate output to - * System.out and System.err respectively. - *

- * Diagnostic logging should be used only to debug problematic - * configurations and should not be set in normal production use. - */ - public static final String DIAGNOSTICS_DEST_PROPERTY = - "org.apache.commons.logging.diagnostics.dest"; - - /** - * When null (the usual case), no diagnostic output will be - * generated by LogFactory or LogFactoryImpl. When non-null, - * interesting events will be written to the specified object. - */ - private static PrintStream diagnosticsStream = null; - - /** - * A string that gets prefixed to every message output by the - * logDiagnostic method, so that users can clearly see which - * LogFactory class is generating the output. - */ - private static String diagnosticPrefix; - - /** - *

Setting this system property - * (org.apache.commons.logging.LogFactory.HashtableImpl) - * value allows the Hashtable used to store - * classloaders to be substituted by an alternative implementation. - *

- *

- * Note: LogFactory will print: - *

-     * [ERROR] LogFactory: Load of custom hashtable failed
-     * 
- * to system error and then continue using a standard Hashtable. - *

- *

- * Usage: Set this property when Java is invoked - * and LogFactory will attempt to load a new instance - * of the given implementation class. - * For example, running the following ant scriplet: - *

-     *  <java classname="${test.runner}" fork="yes" failonerror="${test.failonerror}">
-     *     ...
-     *     <sysproperty 
-     *        key="org.apache.commons.logging.LogFactory.HashtableImpl"
-     *        value="org.apache.commons.logging.AltHashtable"/>
-     *  </java>
-     * 
- * will mean that LogFactory will load an instance of - * org.apache.commons.logging.AltHashtable. - *

- *

- * A typical use case is to allow a custom - * Hashtable implementation using weak references to be substituted. - * This will allow classloaders to be garbage collected without - * the need to release them (on 1.3+ JVMs only, of course ;) - *

- */ - public static final String HASHTABLE_IMPLEMENTATION_PROPERTY = - "org.apache.commons.logging.LogFactory.HashtableImpl"; - /** Name used to load the weak hashtable implementation by names */ - private static final String WEAK_HASHTABLE_CLASSNAME = - "org.apache.commons.logging.impl.WeakHashtable"; - - /** - * A reference to the classloader that loaded this class. This is the - * same as LogFactory.class.getClassLoader(). However computing this - * value isn't quite as simple as that, as we potentially need to use - * AccessControllers etc. It's more efficient to compute it once and - * cache it here. - */ - private static ClassLoader thisClassLoader; - - // ----------------------------------------------------------- Constructors - - - /** - * Protected constructor that is not available for public use. - */ - protected LogFactory() { - } - - // --------------------------------------------------------- Public Methods - - - /** - * Return the configuration attribute with the specified name (if any), - * or null if there is no such attribute. - * - * @param name Name of the attribute to return - */ - public abstract Object getAttribute(String name); - - - /** - * Return an array containing the names of all currently defined - * configuration attributes. If there are no such attributes, a zero - * length array is returned. - */ - public abstract String[] getAttributeNames(); - - - /** - * Convenience method to derive a name from the specified class and - * call getInstance(String) with it. - * - * @param clazz Class for which a suitable Log name will be derived - * - * @exception LogConfigurationException if a suitable Log - * instance cannot be returned - */ - public abstract Log getInstance(Class clazz) - throws LogConfigurationException; - - - /** - *

Construct (if necessary) and return a Log instance, - * using the factory's current set of configuration attributes.

- * - *

NOTE - Depending upon the implementation of - * the LogFactory you are using, the Log - * instance you are returned may or may not be local to the current - * application, and may or may not be returned again on a subsequent - * call with the same name argument.

- * - * @param name Logical name of the Log instance to be - * returned (the meaning of this name is only known to the underlying - * logging implementation that is being wrapped) - * - * @exception LogConfigurationException if a suitable Log - * instance cannot be returned - */ - public abstract Log getInstance(String name) - throws LogConfigurationException; - - - /** - * Release any internal references to previously created {@link Log} - * instances returned by this factory. This is useful in environments - * like servlet containers, which implement application reloading by - * throwing away a ClassLoader. Dangling references to objects in that - * class loader would prevent garbage collection. - */ - public abstract void release(); - - - /** - * Remove any configuration attribute associated with the specified name. - * If there is no such attribute, no action is taken. - * - * @param name Name of the attribute to remove - */ - public abstract void removeAttribute(String name); - - - /** - * Set the configuration attribute with the specified name. Calling - * this with a null value is equivalent to calling - * removeAttribute(name). - * - * @param name Name of the attribute to set - * @param value Value of the attribute to set, or null - * to remove any setting for this attribute - */ - public abstract void setAttribute(String name, Object value); - - - // ------------------------------------------------------- Static Variables - - - /** - * The previously constructed LogFactory instances, keyed by - * the ClassLoader with which it was created. - */ - protected static Hashtable factories = null; - - /** - * Prevously constructed LogFactory instance as in the - * factories map, but for the case where - * getClassLoader returns null. - * This can happen when: - * - * Note that factories is a Hashtable (not a HashMap), - * and hashtables don't allow null as a key. - */ - protected static LogFactory nullClassLoaderFactory = null; - - /** - * Create the hashtable which will be used to store a map of - * (context-classloader -> logfactory-object). Version 1.2+ of Java - * supports "weak references", allowing a custom Hashtable class - * to be used which uses only weak references to its keys. Using weak - * references can fix memory leaks on webapp unload in some cases (though - * not all). Version 1.1 of Java does not support weak references, so we - * must dynamically determine which we are using. And just for fun, this - * code also supports the ability for a system property to specify an - * arbitrary Hashtable implementation name. - *

- * Note that the correct way to ensure no memory leaks occur is to ensure - * that LogFactory.release(contextClassLoader) is called whenever a - * webapp is undeployed. - */ - private static final Hashtable createFactoryStore() { - Hashtable result = null; - String storeImplementationClass; - try { - storeImplementationClass = getSystemProperty(HASHTABLE_IMPLEMENTATION_PROPERTY, null); - } catch(SecurityException ex) { - // Permissions don't allow this to be accessed. Default to the "modern" - // weak hashtable implementation if it is available. - storeImplementationClass = null; - } - - if (storeImplementationClass == null) { - storeImplementationClass = WEAK_HASHTABLE_CLASSNAME; - } - try { - Class implementationClass = Class.forName(storeImplementationClass); - result = (Hashtable) implementationClass.newInstance(); - - } catch (Throwable t) { - // ignore - if (!WEAK_HASHTABLE_CLASSNAME.equals(storeImplementationClass)) { - // if the user's trying to set up a custom implementation, give a clue - if (isDiagnosticsEnabled()) { - // use internal logging to issue the warning - logDiagnostic("[ERROR] LogFactory: Load of custom hashtable failed"); - } else { - // we *really* want this output, even if diagnostics weren't - // explicitly enabled by the user. - System.err.println("[ERROR] LogFactory: Load of custom hashtable failed"); - } - } - } - if (result == null) { - result = new Hashtable(); - } - return result; - } - - - // --------------------------------------------------------- Static Methods - - /** Utility method to safely trim a string. */ - private static String trim(String src) { - if (src == null) { - return null; - } - return src.trim(); - } - - /** - *

Construct (if necessary) and return a LogFactory - * instance, using the following ordered lookup procedure to determine - * the name of the implementation class to be loaded.

- * - * - *

NOTE - If the properties file method of identifying the - * LogFactory implementation class is utilized, all of the - * properties defined in this file will be set as configuration attributes - * on the corresponding LogFactory instance.

- * - *

NOTE - In a multithreaded environment it is possible - * that two different instances will be returned for the same - * classloader environment. - *

- * - * @exception LogConfigurationException if the implementation class is not - * available or cannot be instantiated. - */ - public static LogFactory getFactory() throws LogConfigurationException { - // Identify the class loader we will be using - ClassLoader contextClassLoader = getContextClassLoaderInternal(); - - if (contextClassLoader == null) { - // This is an odd enough situation to report about. This - // output will be a nuisance on JDK1.1, as the system - // classloader is null in that environment. - if (isDiagnosticsEnabled()) { - logDiagnostic("Context classloader is null."); - } - } - - // Return any previously registered factory for this class loader - LogFactory factory = getCachedFactory(contextClassLoader); - if (factory != null) { - return factory; - } - - if (isDiagnosticsEnabled()) { - logDiagnostic( - "[LOOKUP] LogFactory implementation requested for the first time for context classloader " - + objectId(contextClassLoader)); - logHierarchy("[LOOKUP] ", contextClassLoader); - } - - // Load properties file. - // - // If the properties file exists, then its contents are used as - // "attributes" on the LogFactory implementation class. One particular - // property may also control which LogFactory concrete subclass is - // used, but only if other discovery mechanisms fail.. - // - // As the properties file (if it exists) will be used one way or - // another in the end we may as well look for it first. - - Properties props = getConfigurationFile(contextClassLoader, FACTORY_PROPERTIES); - - // Determine whether we will be using the thread context class loader to - // load logging classes or not by checking the loaded properties file (if any). - ClassLoader baseClassLoader = contextClassLoader; - if (props != null) { - String useTCCLStr = props.getProperty(TCCL_KEY); - if (useTCCLStr != null) { - // The Boolean.valueOf(useTCCLStr).booleanValue() formulation - // is required for Java 1.2 compatability. - if (Boolean.valueOf(useTCCLStr).booleanValue() == false) { - // Don't use current context classloader when locating any - // LogFactory or Log classes, just use the class that loaded - // this abstract class. When this class is deployed in a shared - // classpath of a container, it means webapps cannot deploy their - // own logging implementations. It also means that it is up to the - // implementation whether to load library-specific config files - // from the TCCL or not. - baseClassLoader = thisClassLoader; - } - } - } - - // Determine which concrete LogFactory subclass to use. - // First, try a global system property - if (isDiagnosticsEnabled()) { - logDiagnostic( - "[LOOKUP] Looking for system property [" + FACTORY_PROPERTY - + "] to define the LogFactory subclass to use..."); - } - - try { - String factoryClass = getSystemProperty(FACTORY_PROPERTY, null); - if (factoryClass != null) { - if (isDiagnosticsEnabled()) { - logDiagnostic( - "[LOOKUP] Creating an instance of LogFactory class '" + factoryClass - + "' as specified by system property " + FACTORY_PROPERTY); - } - - factory = newFactory(factoryClass, baseClassLoader, contextClassLoader); - } else { - if (isDiagnosticsEnabled()) { - logDiagnostic( - "[LOOKUP] No system property [" + FACTORY_PROPERTY - + "] defined."); - } - } - } catch (SecurityException e) { - if (isDiagnosticsEnabled()) { - logDiagnostic( - "[LOOKUP] A security exception occurred while trying to create an" - + " instance of the custom factory class" - + ": [" + trim(e.getMessage()) - + "]. Trying alternative implementations..."); - } - ; // ignore - } catch(RuntimeException e) { - // This is not consistent with the behaviour when a bad LogFactory class is - // specified in a services file. - // - // One possible exception that can occur here is a ClassCastException when - // the specified class wasn't castable to this LogFactory type. - if (isDiagnosticsEnabled()) { - logDiagnostic( - "[LOOKUP] An exception occurred while trying to create an" - + " instance of the custom factory class" - + ": [" + trim(e.getMessage()) - + "] as specified by a system property."); - } - throw e; - } - - - // Second, try to find a service by using the JDK1.3 class - // discovery mechanism, which involves putting a file with the name - // of an interface class in the META-INF/services directory, where the - // contents of the file is a single line specifying a concrete class - // that implements the desired interface. - - if (factory == null) { - if (isDiagnosticsEnabled()) { - logDiagnostic( - "[LOOKUP] Looking for a resource file of name [" + SERVICE_ID - + "] to define the LogFactory subclass to use..."); - } - try { - InputStream is = getResourceAsStream(contextClassLoader, - SERVICE_ID); - - if( is != null ) { - // This code is needed by EBCDIC and other strange systems. - // It's a fix for bugs reported in xerces - BufferedReader rd; - try { - rd = new BufferedReader(new InputStreamReader(is, "UTF-8")); - } catch (java.io.UnsupportedEncodingException e) { - rd = new BufferedReader(new InputStreamReader(is)); - } - - String factoryClassName = rd.readLine(); - rd.close(); - - if (factoryClassName != null && - ! "".equals(factoryClassName)) { - if (isDiagnosticsEnabled()) { - logDiagnostic( - "[LOOKUP] Creating an instance of LogFactory class " + factoryClassName - + " as specified by file '" + SERVICE_ID - + "' which was present in the path of the context" - + " classloader."); - } - factory = newFactory(factoryClassName, baseClassLoader, contextClassLoader ); - } - } else { - // is == null - if (isDiagnosticsEnabled()) { - logDiagnostic( - "[LOOKUP] No resource file with name '" + SERVICE_ID - + "' found."); - } - } - } catch( Exception ex ) { - // note: if the specified LogFactory class wasn't compatible with LogFactory - // for some reason, a ClassCastException will be caught here, and attempts will - // continue to find a compatible class. - if (isDiagnosticsEnabled()) { - logDiagnostic( - "[LOOKUP] A security exception occurred while trying to create an" - + " instance of the custom factory class" - + ": [" + trim(ex.getMessage()) - + "]. Trying alternative implementations..."); - } - ; // ignore - } - } - - - // Third try looking into the properties file read earlier (if found) - - if (factory == null) { - if (props != null) { - if (isDiagnosticsEnabled()) { - logDiagnostic( - "[LOOKUP] Looking in properties file for entry with key '" - + FACTORY_PROPERTY - + "' to define the LogFactory subclass to use..."); - } - String factoryClass = props.getProperty(FACTORY_PROPERTY); - if (factoryClass != null) { - if (isDiagnosticsEnabled()) { - logDiagnostic( - "[LOOKUP] Properties file specifies LogFactory subclass '" - + factoryClass + "'"); - } - factory = newFactory(factoryClass, baseClassLoader, contextClassLoader); - - // TODO: think about whether we need to handle exceptions from newFactory - } else { - if (isDiagnosticsEnabled()) { - logDiagnostic( - "[LOOKUP] Properties file has no entry specifying LogFactory subclass."); - } - } - } else { - if (isDiagnosticsEnabled()) { - logDiagnostic( - "[LOOKUP] No properties file available to determine" - + " LogFactory subclass from.."); - } - } - } - - - // Fourth, try the fallback implementation class - - if (factory == null) { - if (isDiagnosticsEnabled()) { - logDiagnostic( - "[LOOKUP] Loading the default LogFactory implementation '" + FACTORY_DEFAULT - + "' via the same classloader that loaded this LogFactory" - + " class (ie not looking in the context classloader)."); - } - - // Note: unlike the above code which can try to load custom LogFactory - // implementations via the TCCL, we don't try to load the default LogFactory - // implementation via the context classloader because: - // * that can cause problems (see comments in newFactory method) - // * no-one should be customising the code of the default class - // Yes, we do give up the ability for the child to ship a newer - // version of the LogFactoryImpl class and have it used dynamically - // by an old LogFactory class in the parent, but that isn't - // necessarily a good idea anyway. - factory = newFactory(FACTORY_DEFAULT, thisClassLoader, contextClassLoader); - } - - if (factory != null) { - /** - * Always cache using context class loader. - */ - cacheFactory(contextClassLoader, factory); - - if( props!=null ) { - Enumeration names = props.propertyNames(); - while (names.hasMoreElements()) { - String name = (String) names.nextElement(); - String value = props.getProperty(name); - factory.setAttribute(name, value); - } - } - } - - return factory; - } - - - /** - * Convenience method to return a named logger, without the application - * having to care about factories. - * - * @param clazz Class from which a log name will be derived - * - * @exception LogConfigurationException if a suitable Log - * instance cannot be returned - */ - public static Log getLog(Class clazz) - throws LogConfigurationException { - - return (getFactory().getInstance(clazz)); - - } - - - /** - * Convenience method to return a named logger, without the application - * having to care about factories. - * - * @param name Logical name of the Log instance to be - * returned (the meaning of this name is only known to the underlying - * logging implementation that is being wrapped) - * - * @exception LogConfigurationException if a suitable Log - * instance cannot be returned - */ - public static Log getLog(String name) - throws LogConfigurationException { - - return (getFactory().getInstance(name)); - - } - - - /** - * Release any internal references to previously created {@link LogFactory} - * instances that have been associated with the specified class loader - * (if any), after calling the instance method release() on - * each of them. - * - * @param classLoader ClassLoader for which to release the LogFactory - */ - public static void release(ClassLoader classLoader) { - - if (isDiagnosticsEnabled()) { - logDiagnostic("Releasing factory for classloader " + objectId(classLoader)); - } - synchronized (factories) { - if (classLoader == null) { - if (nullClassLoaderFactory != null) { - nullClassLoaderFactory.release(); - nullClassLoaderFactory = null; - } - } else { - LogFactory factory = (LogFactory) factories.get(classLoader); - if (factory != null) { - factory.release(); - factories.remove(classLoader); - } - } - } - - } - - - /** - * Release any internal references to previously created {@link LogFactory} - * instances, after calling the instance method release() on - * each of them. This is useful in environments like servlet containers, - * which implement application reloading by throwing away a ClassLoader. - * Dangling references to objects in that class loader would prevent - * garbage collection. - */ - public static void releaseAll() { - - if (isDiagnosticsEnabled()) { - logDiagnostic("Releasing factory for all classloaders."); - } - synchronized (factories) { - Enumeration elements = factories.elements(); - while (elements.hasMoreElements()) { - LogFactory element = (LogFactory) elements.nextElement(); - element.release(); - } - factories.clear(); - - if (nullClassLoaderFactory != null) { - nullClassLoaderFactory.release(); - nullClassLoaderFactory = null; - } - } - - } - - - // ------------------------------------------------------ Protected Methods - - /** - * Safely get access to the classloader for the specified class. - *

- * Theoretically, calling getClassLoader can throw a security exception, - * and so should be done under an AccessController in order to provide - * maximum flexibility. However in practice people don't appear to use - * security policies that forbid getClassLoader calls. So for the moment - * all code is written to call this method rather than Class.getClassLoader, - * so that we could put AccessController stuff in this method without any - * disruption later if we need to. - *

- * Even when using an AccessController, however, this method can still - * throw SecurityException. Commons-logging basically relies on the - * ability to access classloaders, ie a policy that forbids all - * classloader access will also prevent commons-logging from working: - * currently this method will throw an exception preventing the entire app - * from starting up. Maybe it would be good to detect this situation and - * just disable all commons-logging? Not high priority though - as stated - * above, security policies that prevent classloader access aren't common. - *

- * Note that returning an object fetched via an AccessController would - * technically be a security flaw anyway; untrusted code that has access - * to a trusted JCL library could use it to fetch the classloader for - * a class even when forbidden to do so directly. - * - * @since 1.1 - */ - protected static ClassLoader getClassLoader(Class clazz) { - try { - return clazz.getClassLoader(); - } catch(SecurityException ex) { - if (isDiagnosticsEnabled()) { - logDiagnostic( - "Unable to get classloader for class '" + clazz - + "' due to security restrictions - " + ex.getMessage()); - } - throw ex; - } - } - - /** - * Returns the current context classloader. - *

- * In versions prior to 1.1, this method did not use an AccessController. - * In version 1.1, an AccessController wrapper was incorrectly added to - * this method, causing a minor security flaw. - *

- * In version 1.1.1 this change was reverted; this method no longer uses - * an AccessController. User code wishing to obtain the context classloader - * must invoke this method via AccessController.doPrivileged if it needs - * support for that. - * - * @return the context classloader associated with the current thread, - * or null if security doesn't allow it. - * - * @throws LogConfigurationException if there was some weird error while - * attempting to get the context classloader. - * - * @throws SecurityException if the current java security policy doesn't - * allow this class to access the context classloader. - */ - protected static ClassLoader getContextClassLoader() - throws LogConfigurationException { - - return directGetContextClassLoader(); - } - - /** - * Calls LogFactory.directGetContextClassLoader under the control of an - * AccessController class. This means that java code running under a - * security manager that forbids access to ClassLoaders will still work - * if this class is given appropriate privileges, even when the caller - * doesn't have such privileges. Without using an AccessController, the - * the entire call stack must have the privilege before the call is - * allowed. - * - * @return the context classloader associated with the current thread, - * or null if security doesn't allow it. - * - * @throws LogConfigurationException if there was some weird error while - * attempting to get the context classloader. - * - * @throws SecurityException if the current java security policy doesn't - * allow this class to access the context classloader. - */ - private static ClassLoader getContextClassLoaderInternal() - throws LogConfigurationException { - return (ClassLoader)AccessController.doPrivileged( - new PrivilegedAction() { - public Object run() { - return directGetContextClassLoader(); - } - }); - } - - /** - * Return the thread context class loader if available; otherwise return - * null. - *

- * Most/all code should call getContextClassLoaderInternal rather than - * calling this method directly. - *

- * The thread context class loader is available for JDK 1.2 - * or later, if certain security conditions are met. - *

- * Note that no internal logging is done within this method because - * this method is called every time LogFactory.getLogger() is called, - * and we don't want too much output generated here. - * - * @exception LogConfigurationException if a suitable class loader - * cannot be identified. - * - * @exception SecurityException if the java security policy forbids - * access to the context classloader from one of the classes in the - * current call stack. - * @since 1.1 - */ - protected static ClassLoader directGetContextClassLoader() - throws LogConfigurationException - { - ClassLoader classLoader = null; - - try { - // Are we running on a JDK 1.2 or later system? - Method method = Thread.class.getMethod("getContextClassLoader", - (Class[]) null); - - // Get the thread context class loader (if there is one) - try { - classLoader = (ClassLoader)method.invoke(Thread.currentThread(), - (Object[]) null); - } catch (IllegalAccessException e) { - throw new LogConfigurationException - ("Unexpected IllegalAccessException", e); - } catch (InvocationTargetException e) { - /** - * InvocationTargetException is thrown by 'invoke' when - * the method being invoked (getContextClassLoader) throws - * an exception. - * - * getContextClassLoader() throws SecurityException when - * the context class loader isn't an ancestor of the - * calling class's class loader, or if security - * permissions are restricted. - * - * In the first case (not related), we want to ignore and - * keep going. We cannot help but also ignore the second - * with the logic below, but other calls elsewhere (to - * obtain a class loader) will trigger this exception where - * we can make a distinction. - */ - if (e.getTargetException() instanceof SecurityException) { - ; // ignore - } else { - // Capture 'e.getTargetException()' exception for details - // alternate: log 'e.getTargetException()', and pass back 'e'. - throw new LogConfigurationException - ("Unexpected InvocationTargetException", e.getTargetException()); - } - } - } catch (NoSuchMethodException e) { - // Assume we are running on JDK 1.1 - classLoader = getClassLoader(LogFactory.class); - - // We deliberately don't log a message here to outputStream; - // this message would be output for every call to LogFactory.getLog() - // when running on JDK1.1 - // - // if (outputStream != null) { - // outputStream.println( - // "Method Thread.getContextClassLoader does not exist;" - // + " assuming this is JDK 1.1, and that the context" - // + " classloader is the same as the class that loaded" - // + " the concrete LogFactory class."); - // } - - } - - // Return the selected class loader - 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 LogFactory - * implementation class, loaded by the specified class loader. - * If that fails, try the class loader used to load this - * (abstract) LogFactory. - *

- *

ClassLoader conflicts

- * 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. - *

- * The problem is the same one that can occur when loading a concrete Log - * subclass via a context classloader. - *

- * 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. - *

- * 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. - *

- * @param factoryClass Fully qualified name of the LogFactory - * 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. - *

- * 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://commons.apache.org/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://commons.apache.org/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 - * 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 LogFactory. - * Diagnostic information is also logged. - *

- * Usage: to diagnose whether a classloader conflict is the cause - * of incompatibility. The test used is whether the class is assignable from - * the LogFactory class loaded by the class's classloader. - * @param logFactoryClass Class which may implement LogFactory - * @return true if the logFactoryClass does extend - * LogFactory when that class is loaded via the same - * classloader that loaded the logFactoryClass. - */ - 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 running 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 - * running 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. - *

- * 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. - *

- * 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. - *

- * 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. - *

- * 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. - *

- * 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. - *

- * 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 '" + fileName - + "' found."); - } else { - logDiagnostic( - "[LOOKUP] Properties file of name '" + fileName - + "' found at '" + propsUrl + '"'); - } - } - - return props; - } - - /** - * Read the specified system property, using an AccessController so that - * the property can be read if JCL has been granted the appropriate - * security rights even if the calling code has not. - *

- * Take care not to expose the value returned by this method to the - * calling application in any way; otherwise the calling app can use that - * info to access data that should not be available to it. - */ - private static String getSystemProperty(final String key, final String def) - throws SecurityException { - return (String) AccessController.doPrivileged( - new PrivilegedAction() { - public Object run() { - return System.getProperty(key, def); - } - }); - } - - /** - * Determines whether the user wants internal diagnostic output. If so, - * returns an appropriate writer object. Users can enable diagnostic - * output by setting the system property named {@link #DIAGNOSTICS_DEST_PROPERTY} to - * a filename, or the special values STDOUT or STDERR. - */ - private static void initDiagnostics() { - String dest; - try { - dest = getSystemProperty(DIAGNOSTICS_DEST_PROPERTY, null); - if (dest == null) { - return; - } - } catch(SecurityException ex) { - // We must be running in some very secure environment. - // We just have to assume output is not wanted.. - return; - } - - if (dest.equals("STDOUT")) { - diagnosticsStream = System.out; - } else if (dest.equals("STDERR")) { - diagnosticsStream = System.err; - } else { - try { - // open the file in append mode - FileOutputStream fos = new FileOutputStream(dest, true); - diagnosticsStream = new PrintStream(fos); - } catch(IOException ex) { - // We should report this to the user - but how? - return; - } - } - - // In order to avoid confusion where multiple instances of JCL are - // being used via different classloaders within the same app, we - // ensure each logged message has a prefix of form - // [LogFactory from classloader OID] - // - // Note that this prefix should be kept consistent with that - // in LogFactoryImpl. However here we don't need to output info - // about the actual *instance* of LogFactory, as all methods that - // output diagnostics from this class are static. - String classLoaderName; - try { - ClassLoader classLoader = thisClassLoader; - if (thisClassLoader == null) { - classLoaderName = "BOOTLOADER"; - } else { - classLoaderName = objectId(classLoader); - } - } catch(SecurityException e) { - classLoaderName = "UNKNOWN"; - } - diagnosticPrefix = "[LogFactory from " + classLoaderName + "] "; - } - - /** - * Indicates true if the user has enabled internal logging. - *

- * By the way, sorry for the incorrect grammar, but calling this method - * areDiagnosticsEnabled just isn't java beans style. - * - * @return true if calls to logDiagnostic will have any effect. - * @since 1.1 - */ - protected static boolean isDiagnosticsEnabled() { - return diagnosticsStream != null; - } - - /** - * Write the specified message to the internal logging destination. - *

- * Note that this method is private; concrete subclasses of this class - * should not call it because the diagnosticPrefix string this - * method puts in front of all its messages is LogFactory@...., - * while subclasses should put SomeSubClass@... - *

- * Subclasses should instead compute their own prefix, then call - * logRawDiagnostic. Note that calling isDiagnosticsEnabled is - * fine for subclasses. - *

- * Note that it is safe to call this method before initDiagnostics - * is called; any output will just be ignored (as isDiagnosticsEnabled - * will return false). - * - * @param msg is the diagnostic message to be output. - */ - private static final void logDiagnostic(String msg) { - if (diagnosticsStream != null) { - diagnosticsStream.print(diagnosticPrefix); - diagnosticsStream.println(msg); - diagnosticsStream.flush(); - } - } - - /** - * Write the specified message to the internal logging destination. - * - * @param msg is the diagnostic message to be output. - * @since 1.1 - */ - protected static final void logRawDiagnostic(String msg) { - if (diagnosticsStream != null) { - diagnosticsStream.println(msg); - diagnosticsStream.flush(); - } - } - - /** - * Generate useful diagnostics regarding the classloader tree for - * the specified class. - *

- * As an example, if the specified class was loaded via a webapp's - * classloader, then you may get the following output: - *

-     * Class com.acme.Foo was loaded via classloader 11111
-     * ClassLoader tree: 11111 -> 22222 (SYSTEM) -> 33333 -> BOOT 
-     * 
- *

- * This method returns immediately if isDiagnosticsEnabled() - * returns false. - * - * @param clazz is the class whose classloader + tree are to be - * output. - */ - private static void logClassLoaderEnvironment(Class clazz) { - if (!isDiagnosticsEnabled()) { - return; - } - - try { - // Deliberately use System.getProperty here instead of getSystemProperty; if - // the overall security policy for the calling application forbids access to - // these variables then we do not want to output them to the diagnostic stream. - logDiagnostic("[ENV] Extension directories (java.ext.dir): " + System.getProperty("java.ext.dir")); - logDiagnostic("[ENV] Application classpath (java.class.path): " + System.getProperty("java.class.path")); - } catch(SecurityException ex) { - logDiagnostic("[ENV] Security setting prevent interrogation of system classpaths."); - } - - String className = clazz.getName(); - ClassLoader classLoader; - - try { - classLoader = getClassLoader(clazz); - } catch(SecurityException ex) { - // not much useful diagnostics we can print here! - logDiagnostic( - "[ENV] Security forbids determining the classloader for " + className); - return; - } - - logDiagnostic( - "[ENV] Class " + className + " was loaded via classloader " - + objectId(classLoader)); - logHierarchy("[ENV] Ancestry of classloader which loaded " + className + " is ", classLoader); - } - - /** - * Logs diagnostic messages about the given classloader - * and it's hierarchy. The prefix is prepended to the message - * and is intended to make it easier to understand the logs. - * @param prefix - * @param classLoader - */ - private static void logHierarchy(String prefix, ClassLoader classLoader) { - if (!isDiagnosticsEnabled()) { - return; - } - ClassLoader systemClassLoader; - if (classLoader != null) { - final String classLoaderString = classLoader.toString(); - logDiagnostic(prefix + objectId(classLoader) + " == '" + classLoaderString + "'"); - } - - try { - systemClassLoader = ClassLoader.getSystemClassLoader(); - } catch(SecurityException ex) { - logDiagnostic( - prefix + "Security forbids determining the system classloader."); - return; - } - if (classLoader != null) { - StringBuffer buf = new StringBuffer(prefix + "ClassLoader tree:"); - for(;;) { - buf.append(objectId(classLoader)); - if (classLoader == systemClassLoader) { - buf.append(" (SYSTEM) "); - } - - try { - classLoader = classLoader.getParent(); - } catch(SecurityException ex) { - buf.append(" --> SECRET"); - break; - } - - buf.append(" --> "); - if (classLoader == null) { - buf.append("BOOT"); - break; - } - } - logDiagnostic(buf.toString()); - } - } - - /** - * Returns a string that uniquely identifies the specified object, including - * its class. - *

- * The returned string is of form "classname@hashcode", ie is the same as - * the return value of the Object.toString() method, but works even when - * the specified object's class has overidden the toString method. - * - * @param o may be null. - * @return a string of form classname@hashcode, or "null" if param o is null. - * @since 1.1 - */ - public static String objectId(Object o) { - if (o == null) { - return "null"; - } else { - return o.getClass().getName() + "@" + System.identityHashCode(o); - } - } - - // ---------------------------------------------------------------------- - // Static initialiser block to perform initialisation at class load time. - // - // We can't do this in the class constructor, as there are many - // static methods on this class that can be called before any - // LogFactory instances are created, and they depend upon this - // stuff having been set up. - // - // Note that this block must come after any variable declarations used - // by any methods called from this block, as we want any static initialiser - // associated with the variable to running first. If static initialisers for - // variables running after this code, then (a) their value might be needed - // by methods called from here, and (b) they might *override* any value - // computed here! - // - // So the wisest thing to do is just to place this code at the very end - // of the class file. - // ---------------------------------------------------------------------- - - static { - // note: it's safe to call methods before initDiagnostics (though - // diagnostic output gets discarded). - thisClassLoader = getClassLoader(LogFactory.class); - initDiagnostics(); - logClassLoaderEnvironment(LogFactory.class); - factories = createFactoryStore(); - if (isDiagnosticsEnabled()) { - logDiagnostic("BOOTSTRAP COMPLETED"); - } - } -} diff --git a/java/src/org/apache/commons/logging/LogSource.java b/java/src/org/apache/commons/logging/LogSource.java deleted file mode 100644 index 9cb5f11..0000000 --- a/java/src/org/apache/commons/logging/LogSource.java +++ /dev/null @@ -1,262 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.commons.logging; - - -import java.lang.reflect.Constructor; -import java.util.Hashtable; - -import org.apache.commons.logging.impl.NoOpLog; - - -/** - *

Factory for creating {@link Log} instances. Applications should call - * the makeNewLogInstance() method to instantiate new instances - * of the configured {@link Log} implementation class.

- * - *

By default, calling getInstance() will use the following - * algorithm:

- * - * - *

You can change the default behavior in one of two ways:

- * - * - * @deprecated Use {@link LogFactory} instead - The default factory - * implementation performs exactly the same algorithm as this class did - * - * @author Rod Waldhoff - * @version $Id: LogSource.java 424107 2006-07-20 23:15:42Z skitching $ - */ -public class LogSource { - - // ------------------------------------------------------- Class Attributes - - static protected Hashtable logs = new Hashtable(); - - /** Is log4j available (in the current classpath) */ - static protected boolean log4jIsAvailable = false; - - /** Is JDK 1.4 logging available */ - static protected boolean jdk14IsAvailable = false; - - /** Constructor for current log class */ - static protected Constructor logImplctor = null; - - - // ----------------------------------------------------- Class Initializers - - static { - - // Is Log4J Available? - try { - if (null != Class.forName("org.apache.log4j.Logger")) { - log4jIsAvailable = true; - } else { - log4jIsAvailable = false; - } - } catch (Throwable t) { - log4jIsAvailable = false; - } - - // Is JDK 1.4 Logging Available? - try { - if ((null != Class.forName("java.util.logging.Logger")) && - (null != Class.forName("org.apache.commons.logging.impl.Jdk14Logger"))) { - jdk14IsAvailable = true; - } else { - jdk14IsAvailable = false; - } - } catch (Throwable t) { - jdk14IsAvailable = false; - } - - // Set the default Log implementation - String name = null; - try { - name = System.getProperty("org.apache.commons.logging.log"); - if (name == null) { - name = System.getProperty("org.apache.commons.logging.Log"); - } - } catch (Throwable t) { - } - if (name != null) { - try { - setLogImplementation(name); - } catch (Throwable t) { - try { - setLogImplementation - ("org.apache.commons.logging.impl.NoOpLog"); - } catch (Throwable u) { - ; - } - } - } else { - try { - if (log4jIsAvailable) { - setLogImplementation - ("org.apache.commons.logging.impl.Log4JLogger"); - } else if (jdk14IsAvailable) { - setLogImplementation - ("org.apache.commons.logging.impl.Jdk14Logger"); - } else { - setLogImplementation - ("org.apache.commons.logging.impl.NoOpLog"); - } - } catch (Throwable t) { - try { - setLogImplementation - ("org.apache.commons.logging.impl.NoOpLog"); - } catch (Throwable u) { - ; - } - } - } - - } - - - // ------------------------------------------------------------ Constructor - - - /** Don't allow others to create instances */ - private LogSource() { - } - - - // ---------------------------------------------------------- Class Methods - - - /** - * Set the log implementation/log implementation factory - * by the name of the class. The given class - * must implement {@link Log}, and provide a constructor that - * takes a single {@link String} argument (containing the name - * of the log). - */ - static public void setLogImplementation(String classname) throws - LinkageError, ExceptionInInitializerError, - NoSuchMethodException, SecurityException, - ClassNotFoundException { - try { - Class logclass = Class.forName(classname); - Class[] argtypes = new Class[1]; - argtypes[0] = "".getClass(); - logImplctor = logclass.getConstructor(argtypes); - } catch (Throwable t) { - logImplctor = null; - } - } - - - /** - * Set the log implementation/log implementation factory - * by class. The given class must implement {@link Log}, - * and provide a constructor that takes a single {@link String} - * argument (containing the name of the log). - */ - static public void setLogImplementation(Class logclass) throws - LinkageError, ExceptionInInitializerError, - NoSuchMethodException, SecurityException { - Class[] argtypes = new Class[1]; - argtypes[0] = "".getClass(); - logImplctor = logclass.getConstructor(argtypes); - } - - - /** Get a Log instance by class name */ - static public Log getInstance(String name) { - Log log = (Log) (logs.get(name)); - if (null == log) { - log = makeNewLogInstance(name); - logs.put(name, log); - } - return log; - } - - - /** Get a Log instance by class */ - static public Log getInstance(Class clazz) { - return getInstance(clazz.getName()); - } - - - /** - * Create a new {@link Log} implementation, based - * on the given name. - *

- * The specific {@link Log} implementation returned - * is determined by the value of the - * org.apache.commons.logging.log property. - * The value of org.apache.commons.logging.log may be set to - * the fully specified name of a class that implements - * the {@link Log} interface. This class must also - * have a public constructor that takes a single - * {@link String} argument (containing the name - * of the {@link Log} to be constructed. - *

- * When org.apache.commons.logging.log is not set, - * or when no corresponding class can be found, - * this method will return a Log4JLogger - * if the log4j Logger class is - * available in the {@link LogSource}'s classpath, or a - * Jdk14Logger if we are on a JDK 1.4 or later system, or - * NoOpLog if neither of the above conditions is true. - * - * @param name the log name (or category) - */ - static public Log makeNewLogInstance(String name) { - - Log log = null; - try { - Object[] args = new Object[1]; - args[0] = name; - log = (Log) (logImplctor.newInstance(args)); - } catch (Throwable t) { - log = null; - } - if (null == log) { - log = new NoOpLog(name); - } - return log; - - } - - - /** - * Returns a {@link String} array containing the names of - * all logs known to me. - */ - static public String[] getLogNames() { - return (String[]) (logs.keySet().toArray(new String[logs.size()])); - } - - -} diff --git a/java/src/org/apache/commons/logging/impl/AvalonLogger.java b/java/src/org/apache/commons/logging/impl/AvalonLogger.java deleted file mode 100644 index df8398c..0000000 --- a/java/src/org/apache/commons/logging/impl/AvalonLogger.java +++ /dev/null @@ -1,292 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.commons.logging.impl; - -import org.apache.avalon.framework.logger.Logger; -import org.apache.commons.logging.Log; - -/** - *

Implementation of commons-logging Log interface that delegates all - * logging calls to the Avalon logging abstraction: the Logger interface. - *

- *

- * There are two ways in which this class can be used: - *

- * - *

- * Note: AvalonLogger does not implement Serializable - * because the constructors available for it make this impossible to achieve in all - * circumstances; there is no way to "reconnect" to an underlying Logger object on - * deserialization if one was just passed in to the constructor of the original - * object. This class was marked Serializable in the 1.0.4 release of - * commons-logging, but this never actually worked (a NullPointerException would - * be thrown as soon as the deserialized object was used), so removing this marker - * is not considered to be an incompatible change. - *

- * @author Neeme Praks - * @version $Revision: 424107 $ $Date: 2006-07-21 01:15:42 +0200 (fr, 21 jul 2006) $ - */ -public class AvalonLogger implements Log { - - /** Ancesteral avalon logger */ - private static Logger defaultLogger = null; - /** Avalon logger used to perform log */ - private transient Logger logger = null; - - /** - * Constructs an AvalonLogger that outputs to the given - * Logger instance. - * @param logger the avalon logger implementation to delegate to - */ - public AvalonLogger(Logger logger) { - this.logger = logger; - } - - /** - * Constructs an AvalonLogger that will log to a child - * of the Logger set by calling {@link #setDefaultLogger}. - * @param name the name of the avalon logger implementation to delegate to - */ - public AvalonLogger(String name) { - if (defaultLogger == null) - throw new NullPointerException("default logger has to be specified if this constructor is used!"); - this.logger = defaultLogger.getChildLogger(name); - } - - /** - * Gets the Avalon logger implementation used to perform logging. - * @return avalon logger implementation - */ - public Logger getLogger() { - return logger; - } - - /** - * Sets the ancesteral Avalon logger from which the delegating loggers - * will descend. - * @param logger the default avalon logger, - * in case there is no logger instance supplied in constructor - */ - public static void setDefaultLogger(Logger logger) { - defaultLogger = logger; - } - - /** - * Logs a message with - * org.apache.avalon.framework.logger.Logger.debug. - * - * @param message to log - * @param t log this cause - * @see org.apache.commons.logging.Log#debug(Object, Throwable) - */ - public void debug(Object message, Throwable t) { - if (getLogger().isDebugEnabled()) getLogger().debug(String.valueOf(message), t); - } - - /** - * Logs a message with - * org.apache.avalon.framework.logger.Logger.debug. - * - * @param message to log. - * @see org.apache.commons.logging.Log#debug(Object) - */ - public void debug(Object message) { - if (getLogger().isDebugEnabled()) getLogger().debug(String.valueOf(message)); - } - - /** - * Logs a message with - * org.apache.avalon.framework.logger.Logger.error. - * - * @param message to log - * @param t log this cause - * @see org.apache.commons.logging.Log#error(Object, Throwable) - */ - public void error(Object message, Throwable t) { - if (getLogger().isErrorEnabled()) getLogger().error(String.valueOf(message), t); - } - - /** - * Logs a message with - * org.apache.avalon.framework.logger.Logger.error. - * - * @param message to log - * @see org.apache.commons.logging.Log#error(Object) - */ - public void error(Object message) { - if (getLogger().isErrorEnabled()) getLogger().error(String.valueOf(message)); - } - - /** - * Logs a message with - * org.apache.avalon.framework.logger.Logger.fatalError. - * - * @param message to log. - * @param t log this cause. - * @see org.apache.commons.logging.Log#fatal(Object, Throwable) - */ - public void fatal(Object message, Throwable t) { - if (getLogger().isFatalErrorEnabled()) getLogger().fatalError(String.valueOf(message), t); - } - - /** - * Logs a message with - * org.apache.avalon.framework.logger.Logger.fatalError. - * - * @param message to log - * @see org.apache.commons.logging.Log#fatal(Object) - */ - public void fatal(Object message) { - if (getLogger().isFatalErrorEnabled()) getLogger().fatalError(String.valueOf(message)); - } - - /** - * Logs a message with - * org.apache.avalon.framework.logger.Logger.info. - * - * @param message to log - * @param t log this cause - * @see org.apache.commons.logging.Log#info(Object, Throwable) - */ - public void info(Object message, Throwable t) { - if (getLogger().isInfoEnabled()) getLogger().info(String.valueOf(message), t); - } - - /** - * Logs a message with - * org.apache.avalon.framework.logger.Logger.info. - * - * @param message to log - * @see org.apache.commons.logging.Log#info(Object) - */ - public void info(Object message) { - if (getLogger().isInfoEnabled()) getLogger().info(String.valueOf(message)); - } - - /** - * Is logging to - * org.apache.avalon.framework.logger.Logger.debug enabled? - * @see org.apache.commons.logging.Log#isDebugEnabled() - */ - public boolean isDebugEnabled() { - return getLogger().isDebugEnabled(); - } - - /** - * Is logging to - * org.apache.avalon.framework.logger.Logger.error enabled? - * @see org.apache.commons.logging.Log#isErrorEnabled() - */ - public boolean isErrorEnabled() { - return getLogger().isErrorEnabled(); - } - - /** - * Is logging to - * org.apache.avalon.framework.logger.Logger.fatalError enabled? - * @see org.apache.commons.logging.Log#isFatalEnabled() - */ - public boolean isFatalEnabled() { - return getLogger().isFatalErrorEnabled(); - } - - /** - * Is logging to - * org.apache.avalon.framework.logger.Logger.info enabled? - * @see org.apache.commons.logging.Log#isInfoEnabled() - */ - public boolean isInfoEnabled() { - return getLogger().isInfoEnabled(); - } - - /** - * Is logging to - * org.apache.avalon.framework.logger.Logger.debug enabled? - * @see org.apache.commons.logging.Log#isTraceEnabled() - */ - public boolean isTraceEnabled() { - return getLogger().isDebugEnabled(); - } - - /** - * Is logging to - * org.apache.avalon.framework.logger.Logger.warn enabled? - * @see org.apache.commons.logging.Log#isWarnEnabled() - */ - public boolean isWarnEnabled() { - return getLogger().isWarnEnabled(); - } - - /** - * Logs a message with - * org.apache.avalon.framework.logger.Logger.debug. - * - * @param message to log. - * @param t log this cause. - * @see org.apache.commons.logging.Log#trace(Object, Throwable) - */ - public void trace(Object message, Throwable t) { - if (getLogger().isDebugEnabled()) getLogger().debug(String.valueOf(message), t); - } - - /** - * Logs a message with - * org.apache.avalon.framework.logger.Logger.debug. - * - * @param message to log - * @see org.apache.commons.logging.Log#trace(Object) - */ - public void trace(Object message) { - if (getLogger().isDebugEnabled()) getLogger().debug(String.valueOf(message)); - } - - /** - * Logs a message with - * org.apache.avalon.framework.logger.Logger.warn. - * - * @param message to log - * @param t log this cause - * @see org.apache.commons.logging.Log#warn(Object, Throwable) - */ - public void warn(Object message, Throwable t) { - if (getLogger().isWarnEnabled()) getLogger().warn(String.valueOf(message), t); - } - - /** - * Logs a message with - * org.apache.avalon.framework.logger.Logger.warn. - * - * @param message to log - * @see org.apache.commons.logging.Log#warn(Object) - */ - public void warn(Object message) { - if (getLogger().isWarnEnabled()) getLogger().warn(String.valueOf(message)); - } - -} diff --git a/java/src/org/apache/commons/logging/impl/Jdk13LumberjackLogger.java b/java/src/org/apache/commons/logging/impl/Jdk13LumberjackLogger.java deleted file mode 100644 index 2188bdc..0000000 --- a/java/src/org/apache/commons/logging/impl/Jdk13LumberjackLogger.java +++ /dev/null @@ -1,335 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - - -package org.apache.commons.logging.impl; - - -import java.io.Serializable; -import java.util.logging.Level; -import java.util.logging.Logger; -import java.util.logging.LogRecord; -import java.util.StringTokenizer; -import java.io.PrintWriter; -import java.io.StringWriter; - -import org.apache.commons.logging.Log; - - -/** - *

Implementation of the org.apache.commons.logging.Log - * interface that wraps the standard JDK logging mechanisms that are - * available in SourceForge's Lumberjack for JDKs prior to 1.4.

- * - * @author Scott Sanders - * @author Berin Loritsch - * @author Peter Donald - * @author Vince Eagen - * @version $Revision: 424107 $ $Date: 2006-07-21 01:15:42 +0200 (fr, 21 jul 2006) $ - * @since 1.1 - */ - -public class Jdk13LumberjackLogger implements Log, Serializable { - - - // ----------------------------------------------------- Instance Variables - - - /** - * The underlying Logger implementation we are using. - */ - protected transient Logger logger = null; - protected String name = null; - private String sourceClassName = "unknown"; - private String sourceMethodName = "unknown"; - private boolean classAndMethodFound = false; - - - /** - * This member variable simply ensures that any attempt to initialise - * this class in a pre-1.4 JVM will result in an ExceptionInInitializerError. - * It must not be private, as an optimising compiler could detect that it - * is not used and optimise it away. - */ - protected static final Level dummyLevel = Level.FINE; - - // ----------------------------------------------------------- Constructors - - - /** - * Construct a named instance of this Logger. - * - * @param name Name of the logger to be constructed - */ - public Jdk13LumberjackLogger(String name) { - - this.name = name; - logger = getLogger(); - - } - - - // --------------------------------------------------------- Public Methods - - - private void log( Level level, String msg, Throwable ex ) { - if( getLogger().isLoggable(level) ) { - LogRecord record = new LogRecord(level, msg); - if( !classAndMethodFound ) { - getClassAndMethod(); - } - record.setSourceClassName(sourceClassName); - record.setSourceMethodName(sourceMethodName); - if( ex != null ) { - record.setThrown(ex); - } - getLogger().log(record); - } - } - - /** - *

Gets the class and method by looking at the stack trace for the - * first entry that is not this class.

- */ - private void getClassAndMethod() { - try { - Throwable throwable = new Throwable(); - throwable.fillInStackTrace(); - StringWriter stringWriter = new StringWriter(); - PrintWriter printWriter = new PrintWriter( stringWriter ); - throwable.printStackTrace( printWriter ); - String traceString = stringWriter.getBuffer().toString(); - StringTokenizer tokenizer = - new StringTokenizer( traceString, "\n" ); - tokenizer.nextToken(); - String line = tokenizer.nextToken(); - while ( line.indexOf( this.getClass().getName() ) == -1 ) { - line = tokenizer.nextToken(); - } - while ( line.indexOf( this.getClass().getName() ) >= 0 ) { - line = tokenizer.nextToken(); - } - int start = line.indexOf( "at " ) + 3; - int end = line.indexOf( '(' ); - String temp = line.substring( start, end ); - int lastPeriod = temp.lastIndexOf( '.' ); - sourceClassName = temp.substring( 0, lastPeriod ); - sourceMethodName = temp.substring( lastPeriod + 1 ); - } catch ( Exception ex ) { - // ignore - leave class and methodname unknown - } - classAndMethodFound = true; - } - - /** - * Logs a message with java.util.logging.Level.FINE. - * - * @param message to log - * @see org.apache.commons.logging.Log#debug(Object) - */ - public void debug(Object message) { - log(Level.FINE, String.valueOf(message), null); - } - - - /** - * Logs a message with java.util.logging.Level.FINE. - * - * @param message to log - * @param exception log this cause - * @see org.apache.commons.logging.Log#debug(Object, Throwable) - */ - public void debug(Object message, Throwable exception) { - log(Level.FINE, String.valueOf(message), exception); - } - - - /** - * Logs a message with java.util.logging.Level.SEVERE. - * - * @param message to log - * @see org.apache.commons.logging.Log#error(Object) - */ - public void error(Object message) { - log(Level.SEVERE, String.valueOf(message), null); - } - - - /** - * Logs a message with java.util.logging.Level.SEVERE. - * - * @param message to log - * @param exception log this cause - * @see org.apache.commons.logging.Log#error(Object, Throwable) - */ - public void error(Object message, Throwable exception) { - log(Level.SEVERE, String.valueOf(message), exception); - } - - - /** - * Logs a message with java.util.logging.Level.SEVERE. - * - * @param message to log - * @see org.apache.commons.logging.Log#fatal(Object) - */ - public void fatal(Object message) { - log(Level.SEVERE, String.valueOf(message), null); - } - - - /** - * Logs a message with java.util.logging.Level.SEVERE. - * - * @param message to log - * @param exception log this cause - * @see org.apache.commons.logging.Log#fatal(Object, Throwable) - */ - public void fatal(Object message, Throwable exception) { - log(Level.SEVERE, String.valueOf(message), exception); - } - - - /** - * Return the native Logger instance we are using. - */ - public Logger getLogger() { - if (logger == null) { - logger = Logger.getLogger(name); - } - return (logger); - } - - - /** - * Logs a message with java.util.logging.Level.INFO. - * - * @param message to log - * @see org.apache.commons.logging.Log#info(Object) - */ - public void info(Object message) { - log(Level.INFO, String.valueOf(message), null); - } - - - /** - * Logs a message with java.util.logging.Level.INFO. - * - * @param message to log - * @param exception log this cause - * @see org.apache.commons.logging.Log#info(Object, Throwable) - */ - public void info(Object message, Throwable exception) { - log(Level.INFO, String.valueOf(message), exception); - } - - - /** - * Is debug logging currently enabled? - */ - public boolean isDebugEnabled() { - return (getLogger().isLoggable(Level.FINE)); - } - - - /** - * Is error logging currently enabled? - */ - public boolean isErrorEnabled() { - return (getLogger().isLoggable(Level.SEVERE)); - } - - - /** - * Is fatal logging currently enabled? - */ - public boolean isFatalEnabled() { - return (getLogger().isLoggable(Level.SEVERE)); - } - - - /** - * Is info logging currently enabled? - */ - public boolean isInfoEnabled() { - return (getLogger().isLoggable(Level.INFO)); - } - - - /** - * Is trace logging currently enabled? - */ - public boolean isTraceEnabled() { - return (getLogger().isLoggable(Level.FINEST)); - } - - - /** - * Is warn logging currently enabled? - */ - public boolean isWarnEnabled() { - return (getLogger().isLoggable(Level.WARNING)); - } - - - /** - * Logs a message with java.util.logging.Level.FINEST. - * - * @param message to log - * @see org.apache.commons.logging.Log#trace(Object) - */ - public void trace(Object message) { - log(Level.FINEST, String.valueOf(message), null); - } - - - /** - * Logs a message with java.util.logging.Level.FINEST. - * - * @param message to log - * @param exception log this cause - * @see org.apache.commons.logging.Log#trace(Object, Throwable) - */ - public void trace(Object message, Throwable exception) { - log(Level.FINEST, String.valueOf(message), exception); - } - - - /** - * Logs a message with java.util.logging.Level.WARNING. - * - * @param message to log - * @see org.apache.commons.logging.Log#warn(Object) - */ - public void warn(Object message) { - log(Level.WARNING, String.valueOf(message), null); - } - - - /** - * Logs a message with java.util.logging.Level.WARNING. - * - * @param message to log - * @param exception log this cause - * @see org.apache.commons.logging.Log#warn(Object, Throwable) - */ - public void warn(Object message, Throwable exception) { - log(Level.WARNING, String.valueOf(message), exception); - } - - -} diff --git a/java/src/org/apache/commons/logging/impl/Jdk14Logger.java b/java/src/org/apache/commons/logging/impl/Jdk14Logger.java deleted file mode 100644 index b8cb510..0000000 --- a/java/src/org/apache/commons/logging/impl/Jdk14Logger.java +++ /dev/null @@ -1,304 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - - -package org.apache.commons.logging.impl; - - -import java.io.Serializable; -import java.util.logging.Level; -import java.util.logging.Logger; - -import org.apache.commons.logging.Log; - - -/** - *

Implementation of the org.apache.commons.logging.Log - * interface that wraps the standard JDK logging mechanisms that were - * introduced in the Merlin release (JDK 1.4).

- * - * @author Scott Sanders - * @author Berin Loritsch - * @author Peter Donald - * @version $Revision: 424107 $ $Date: 2006-07-21 01:15:42 +0200 (fr, 21 jul 2006) $ - */ - -public class Jdk14Logger implements Log, Serializable { - - /** - * This member variable simply ensures that any attempt to initialise - * this class in a pre-1.4 JVM will result in an ExceptionInInitializerError. - * It must not be private, as an optimising compiler could detect that it - * is not used and optimise it away. - */ - protected static final Level dummyLevel = Level.FINE; - - // ----------------------------------------------------------- Constructors - - - /** - * Construct a named instance of this Logger. - * - * @param name Name of the logger to be constructed - */ - public Jdk14Logger(String name) { - - this.name = name; - logger = getLogger(); - - } - - - // ----------------------------------------------------- Instance Variables - - - /** - * The underlying Logger implementation we are using. - */ - protected transient Logger logger = null; - - - /** - * The name of the logger we are wrapping. - */ - protected String name = null; - - - // --------------------------------------------------------- Public Methods - - private void log( Level level, String msg, Throwable ex ) { - - Logger logger = getLogger(); - if (logger.isLoggable(level)) { - // Hack (?) to get the stack trace. - Throwable dummyException=new Throwable(); - StackTraceElement locations[]=dummyException.getStackTrace(); - // Caller will be the third element - String cname="unknown"; - String method="unknown"; - if( locations!=null && locations.length >2 ) { - StackTraceElement caller=locations[2]; - cname=caller.getClassName(); - method=caller.getMethodName(); - } - if( ex==null ) { - logger.logp( level, cname, method, msg ); - } else { - logger.logp( level, cname, method, msg, ex ); - } - } - - } - - /** - * Logs a message with java.util.logging.Level.FINE. - * - * @param message to log - * @see org.apache.commons.logging.Log#debug(Object) - */ - public void debug(Object message) { - log(Level.FINE, String.valueOf(message), null); - } - - - /** - * Logs a message with java.util.logging.Level.FINE. - * - * @param message to log - * @param exception log this cause - * @see org.apache.commons.logging.Log#debug(Object, Throwable) - */ - public void debug(Object message, Throwable exception) { - log(Level.FINE, String.valueOf(message), exception); - } - - - /** - * Logs a message with java.util.logging.Level.SEVERE. - * - * @param message to log - * @see org.apache.commons.logging.Log#error(Object) - */ - public void error(Object message) { - log(Level.SEVERE, String.valueOf(message), null); - } - - - /** - * Logs a message with java.util.logging.Level.SEVERE. - * - * @param message to log - * @param exception log this cause - * @see org.apache.commons.logging.Log#error(Object, Throwable) - */ - public void error(Object message, Throwable exception) { - log(Level.SEVERE, String.valueOf(message), exception); - } - - - /** - * Logs a message with java.util.logging.Level.SEVERE. - * - * @param message to log - * @see org.apache.commons.logging.Log#fatal(Object) - */ - public void fatal(Object message) { - log(Level.SEVERE, String.valueOf(message), null); - } - - - /** - * Logs a message with java.util.logging.Level.SEVERE. - * - * @param message to log - * @param exception log this cause - * @see org.apache.commons.logging.Log#fatal(Object, Throwable) - */ - public void fatal(Object message, Throwable exception) { - log(Level.SEVERE, String.valueOf(message), exception); - } - - - /** - * Return the native Logger instance we are using. - */ - public Logger getLogger() { - if (logger == null) { - logger = Logger.getLogger(name); - } - return (logger); - } - - - /** - * Logs a message with java.util.logging.Level.INFO. - * - * @param message to log - * @see org.apache.commons.logging.Log#info(Object) - */ - public void info(Object message) { - log(Level.INFO, String.valueOf(message), null); - } - - - /** - * Logs a message with java.util.logging.Level.INFO. - * - * @param message to log - * @param exception log this cause - * @see org.apache.commons.logging.Log#info(Object, Throwable) - */ - public void info(Object message, Throwable exception) { - log(Level.INFO, String.valueOf(message), exception); - } - - - /** - * Is debug logging currently enabled? - */ - public boolean isDebugEnabled() { - return (getLogger().isLoggable(Level.FINE)); - } - - - /** - * Is error logging currently enabled? - */ - public boolean isErrorEnabled() { - return (getLogger().isLoggable(Level.SEVERE)); - } - - - /** - * Is fatal logging currently enabled? - */ - public boolean isFatalEnabled() { - return (getLogger().isLoggable(Level.SEVERE)); - } - - - /** - * Is info logging currently enabled? - */ - public boolean isInfoEnabled() { - return (getLogger().isLoggable(Level.INFO)); - } - - - /** - * Is trace logging currently enabled? - */ - public boolean isTraceEnabled() { - return (getLogger().isLoggable(Level.FINEST)); - } - - - /** - * Is warn logging currently enabled? - */ - public boolean isWarnEnabled() { - return (getLogger().isLoggable(Level.WARNING)); - } - - - /** - * Logs a message with java.util.logging.Level.FINEST. - * - * @param message to log - * @see org.apache.commons.logging.Log#trace(Object) - */ - public void trace(Object message) { - log(Level.FINEST, String.valueOf(message), null); - } - - - /** - * Logs a message with java.util.logging.Level.FINEST. - * - * @param message to log - * @param exception log this cause - * @see org.apache.commons.logging.Log#trace(Object, Throwable) - */ - public void trace(Object message, Throwable exception) { - log(Level.FINEST, String.valueOf(message), exception); - } - - - /** - * Logs a message with java.util.logging.Level.WARNING. - * - * @param message to log - * @see org.apache.commons.logging.Log#warn(Object) - */ - public void warn(Object message) { - log(Level.WARNING, String.valueOf(message), null); - } - - - /** - * Logs a message with java.util.logging.Level.WARNING. - * - * @param message to log - * @param exception log this cause - * @see org.apache.commons.logging.Log#warn(Object, Throwable) - */ - public void warn(Object message, Throwable exception) { - log(Level.WARNING, String.valueOf(message), exception); - } - - -} diff --git a/java/src/org/apache/commons/logging/impl/Log4JLogger.java b/java/src/org/apache/commons/logging/impl/Log4JLogger.java deleted file mode 100644 index 56d421e..0000000 --- a/java/src/org/apache/commons/logging/impl/Log4JLogger.java +++ /dev/null @@ -1,342 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - - -package org.apache.commons.logging.impl; - -import java.io.Serializable; -import org.apache.commons.logging.Log; -import org.apache.log4j.Logger; -import org.apache.log4j.Priority; -import org.apache.log4j.Level; - -/** - * Implementation of {@link Log} that maps directly to a - * Logger for log4J version 1.2. - *

- * Initial configuration of the corresponding Logger instances should be done - * in the usual manner, as outlined in the Log4J documentation. - *

- * The reason this logger is distinct from the 1.3 logger is that in version 1.2 - * of Log4J: - *

- * Log4J1.3 is expected to change Level so it no longer extends Priority, which is - * a non-binary-compatible change. The class generated by compiling this code against - * log4j 1.2 will therefore not running against log4j 1.3. - * - * @author Scott Sanders - * @author Rod Waldhoff - * @author Robert Burrell Donkin - * @version $Id: Log4JLogger.java 479747 2006-11-27 20:15:01Z dennisl $ - */ - -public class Log4JLogger implements Log, Serializable { - - // ------------------------------------------------------------- Attributes - - /** The fully qualified name of the Log4JLogger class. */ - private static final String FQCN = Log4JLogger.class.getName(); - - /** Log to this logger */ - private transient Logger logger = null; - - /** Logger name */ - private String name = null; - - private static Priority traceLevel; - - // ------------------------------------------------------------ - // Static Initializer. - // - // Note that this must come after the static variable declarations - // otherwise initialiser expressions associated with those variables - // will override any settings done here. - // - // Verify that log4j is available, and that it is version 1.2. - // If an ExceptionInInitializerError is generated, then LogFactoryImpl - // will treat that as meaning that the appropriate underlying logging - // library is just not present - if discovery is in progress then - // discovery will continue. - // ------------------------------------------------------------ - - static { - if (!Priority.class.isAssignableFrom(Level.class)) { - // nope, this is log4j 1.3, so force an ExceptionInInitializerError - throw new InstantiationError("Log4J 1.2 not available"); - } - - // Releases of log4j1.2 >= 1.2.12 have Priority.TRACE available, earlier - // versions do not. If TRACE is not available, then we have to map - // calls to Log.trace(...) onto the DEBUG level. - - try { - traceLevel = (Priority) Level.class.getDeclaredField("TRACE").get(null); - } catch(Exception ex) { - // ok, trace not available - traceLevel = Priority.DEBUG; - } - } - - - // ------------------------------------------------------------ Constructor - - public Log4JLogger() { - } - - - /** - * Base constructor. - */ - public Log4JLogger(String name) { - this.name = name; - this.logger = getLogger(); - } - - /** - * For use with a log4j factory. - */ - public Log4JLogger(Logger logger ) { - if (logger == null) { - throw new IllegalArgumentException( - "Warning - null logger in constructor; possible log4j misconfiguration."); - } - this.name = logger.getName(); - this.logger=logger; - } - - - // --------------------------------------------------------- - // Implementation - // - // Note that in the methods below the Priority class is used to define - // levels even though the Level class is supported in 1.2. This is done - // so that at compile time the call definitely resolves to a call to - // a method that takes a Priority rather than one that takes a Level. - // - // The Category class (and hence its subclass Logger) in version 1.2 only - // has methods that take Priority objects. The Category class (and hence - // Logger class) in version 1.3 has methods that take both Priority and - // Level objects. This means that if we use Level here, and compile - // against log4j 1.3 then calls would be bound to the versions of - // methods taking Level objects and then would fail to running against - // version 1.2 of log4j. - // --------------------------------------------------------- - - - /** - * Logs a message with org.apache.log4j.Priority.TRACE. - * When using a log4j version that does not support the TRACE - * level, the message will be logged at the DEBUG level. - * - * @param message to log - * @see org.apache.commons.logging.Log#trace(Object) - */ - public void trace(Object message) { - getLogger().log(FQCN, traceLevel, message, null ); - } - - - /** - * Logs a message with org.apache.log4j.Priority.TRACE. - * When using a log4j version that does not support the TRACE - * level, the message will be logged at the DEBUG level. - * - * @param message to log - * @param t log this cause - * @see org.apache.commons.logging.Log#trace(Object, Throwable) - */ - public void trace(Object message, Throwable t) { - getLogger().log(FQCN, traceLevel, message, t ); - } - - - /** - * Logs a message with org.apache.log4j.Priority.DEBUG. - * - * @param message to log - * @see org.apache.commons.logging.Log#debug(Object) - */ - public void debug(Object message) { - getLogger().log(FQCN, Priority.DEBUG, message, null ); - } - - /** - * Logs a message with org.apache.log4j.Priority.DEBUG. - * - * @param message to log - * @param t log this cause - * @see org.apache.commons.logging.Log#debug(Object, Throwable) - */ - public void debug(Object message, Throwable t) { - getLogger().log(FQCN, Priority.DEBUG, message, t ); - } - - - /** - * Logs a message with org.apache.log4j.Priority.INFO. - * - * @param message to log - * @see org.apache.commons.logging.Log#info(Object) - */ - public void info(Object message) { - getLogger().log(FQCN, Priority.INFO, message, null ); - } - - - /** - * Logs a message with org.apache.log4j.Priority.INFO. - * - * @param message to log - * @param t log this cause - * @see org.apache.commons.logging.Log#info(Object, Throwable) - */ - public void info(Object message, Throwable t) { - getLogger().log(FQCN, Priority.INFO, message, t ); - } - - - /** - * Logs a message with org.apache.log4j.Priority.WARN. - * - * @param message to log - * @see org.apache.commons.logging.Log#warn(Object) - */ - public void warn(Object message) { - getLogger().log(FQCN, Priority.WARN, message, null ); - } - - - /** - * Logs a message with org.apache.log4j.Priority.WARN. - * - * @param message to log - * @param t log this cause - * @see org.apache.commons.logging.Log#warn(Object, Throwable) - */ - public void warn(Object message, Throwable t) { - getLogger().log(FQCN, Priority.WARN, message, t ); - } - - - /** - * Logs a message with org.apache.log4j.Priority.ERROR. - * - * @param message to log - * @see org.apache.commons.logging.Log#error(Object) - */ - public void error(Object message) { - getLogger().log(FQCN, Priority.ERROR, message, null ); - } - - - /** - * Logs a message with org.apache.log4j.Priority.ERROR. - * - * @param message to log - * @param t log this cause - * @see org.apache.commons.logging.Log#error(Object, Throwable) - */ - public void error(Object message, Throwable t) { - getLogger().log(FQCN, Priority.ERROR, message, t ); - } - - - /** - * Logs a message with org.apache.log4j.Priority.FATAL. - * - * @param message to log - * @see org.apache.commons.logging.Log#fatal(Object) - */ - public void fatal(Object message) { - getLogger().log(FQCN, Priority.FATAL, message, null ); - } - - - /** - * Logs a message with org.apache.log4j.Priority.FATAL. - * - * @param message to log - * @param t log this cause - * @see org.apache.commons.logging.Log#fatal(Object, Throwable) - */ - public void fatal(Object message, Throwable t) { - getLogger().log(FQCN, Priority.FATAL, message, t ); - } - - - /** - * Return the native Logger instance we are using. - */ - public Logger getLogger() { - if (logger == null) { - logger = Logger.getLogger(name); - } - return (this.logger); - } - - - /** - * Check whether the Log4j Logger used is enabled for DEBUG priority. - */ - public boolean isDebugEnabled() { - return getLogger().isDebugEnabled(); - } - - - /** - * Check whether the Log4j Logger used is enabled for ERROR priority. - */ - public boolean isErrorEnabled() { - return getLogger().isEnabledFor(Priority.ERROR); - } - - - /** - * Check whether the Log4j Logger used is enabled for FATAL priority. - */ - public boolean isFatalEnabled() { - return getLogger().isEnabledFor(Priority.FATAL); - } - - - /** - * Check whether the Log4j Logger used is enabled for INFO priority. - */ - public boolean isInfoEnabled() { - return getLogger().isInfoEnabled(); - } - - - /** - * Check whether the Log4j Logger used is enabled for TRACE priority. - * When using a log4j version that does not support the TRACE level, this call - * will report whether DEBUG is enabled or not. - */ - public boolean isTraceEnabled() { - return getLogger().isEnabledFor(traceLevel); - } - - /** - * Check whether the Log4j Logger used is enabled for WARN priority. - */ - public boolean isWarnEnabled() { - return getLogger().isEnabledFor(Priority.WARN); - } -} diff --git a/java/src/org/apache/commons/logging/impl/LogFactoryImpl.java b/java/src/org/apache/commons/logging/impl/LogFactoryImpl.java deleted file mode 100644 index 20c8a36..0000000 --- a/java/src/org/apache/commons/logging/impl/LogFactoryImpl.java +++ /dev/null @@ -1,1500 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.commons.logging.impl; - - -import java.lang.reflect.Constructor; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.net.URL; -import java.security.AccessController; -import java.security.PrivilegedAction; -import java.util.Enumeration; -import java.util.Hashtable; -import java.util.Vector; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogConfigurationException; -import org.apache.commons.logging.LogFactory; - - -/** - *

Concrete subclass of {@link LogFactory} that implements the - * following algorithm to dynamically select a logging implementation - * class to instantiate a wrapper for.

- * - * - *

If the selected {@link Log} implementation class has a - * setLogFactory() method that accepts a {@link LogFactory} - * parameter, this method will be called on each newly created instance - * to identify the associated factory. This makes factory configuration - * attributes available to the Log instance, if it so desires.

- * - *

This factory will remember previously created Log instances - * for the same name, and will return them on repeated requests to the - * getInstance() method.

- * - * @author Rod Waldhoff - * @author Craig R. McClanahan - * @author Richard A. Sitze - * @author Brian Stansberry - * @version $Revision: 581090 $ $Date: 2007-10-02 00:01:06 +0200 (ti, 02 okt 2007) $ - */ - -public class LogFactoryImpl extends LogFactory { - - - /** Log4JLogger class name */ - private static final String LOGGING_IMPL_LOG4J_LOGGER = "org.apache.commons.logging.impl.Log4JLogger"; - /** Jdk14Logger class name */ - private static final String LOGGING_IMPL_JDK14_LOGGER = "org.apache.commons.logging.impl.Jdk14Logger"; - /** Jdk13LumberjackLogger class name */ - private static final String LOGGING_IMPL_LUMBERJACK_LOGGER = "org.apache.commons.logging.impl.Jdk13LumberjackLogger"; - /** SimpleLog class name */ - private static final String LOGGING_IMPL_SIMPLE_LOGGER = "org.apache.commons.logging.impl.SimpleLog"; - - private static final String PKG_IMPL="org.apache.commons.logging.impl."; - private static final int PKG_LEN = PKG_IMPL.length(); - - // ----------------------------------------------------------- Constructors - - - - /** - * Public no-arguments constructor required by the lookup mechanism. - */ - public LogFactoryImpl() { - super(); - initDiagnostics(); // method on this object - if (isDiagnosticsEnabled()) { - logDiagnostic("Instance created."); - } - } - - - // ----------------------------------------------------- Manifest Constants - - - /** - * The name (org.apache.commons.logging.Log) of the system - * property identifying our {@link Log} implementation class. - */ - public static final String LOG_PROPERTY = - "org.apache.commons.logging.Log"; - - - /** - * The deprecated system property used for backwards compatibility with - * old versions of JCL. - */ - protected static final String LOG_PROPERTY_OLD = - "org.apache.commons.logging.log"; - - /** - * The name (org.apache.commons.logging.Log.allowFlawedContext) - * of the system property which can be set true/false to - * determine system behaviour when a bad context-classloader is encountered. - * When set to false, a LogConfigurationException is thrown if - * LogFactoryImpl is loaded via a child classloader of the TCCL (this - * should never happen in sane systems). - * - * Default behaviour: true (tolerates bad context classloaders) - * - * See also method setAttribute. - */ - public static final String ALLOW_FLAWED_CONTEXT_PROPERTY = - "org.apache.commons.logging.Log.allowFlawedContext"; - - /** - * The name (org.apache.commons.logging.Log.allowFlawedDiscovery) - * of the system property which can be set true/false to - * determine system behaviour when a bad logging adapter class is - * encountered during logging discovery. When set to false, an - * exception will be thrown and the app will fail to start. When set - * to true, discovery will continue (though the user might end up - * with a different logging implementation than they expected). - * - * Default behaviour: true (tolerates bad logging adapters) - * - * See also method setAttribute. - */ - public static final String ALLOW_FLAWED_DISCOVERY_PROPERTY = - "org.apache.commons.logging.Log.allowFlawedDiscovery"; - - /** - * The name (org.apache.commons.logging.Log.allowFlawedHierarchy) - * of the system property which can be set true/false to - * determine system behaviour when a logging adapter class is - * encountered which has bound to the wrong Log class implementation. - * When set to false, an exception will be thrown and the app will fail - * to start. When set to true, discovery will continue (though the user - * might end up with a different logging implementation than they expected). - * - * Default behaviour: true (tolerates bad Log class hierarchy) - * - * See also method setAttribute. - */ - public static final String ALLOW_FLAWED_HIERARCHY_PROPERTY = - "org.apache.commons.logging.Log.allowFlawedHierarchy"; - - - /** - * The names of classes that will be tried (in order) as logging - * adapters. Each class is expected to implement the Log interface, - * and to throw NoClassDefFound or ExceptionInInitializerError when - * loaded if the underlying logging library is not available. Any - * other error indicates that the underlying logging library is available - * but broken/unusable for some reason. - */ - private static final String[] classesToDiscover = { - LOGGING_IMPL_LOG4J_LOGGER, - "org.apache.commons.logging.impl.Jdk14Logger", - "org.apache.commons.logging.impl.Jdk13LumberjackLogger", - "org.apache.commons.logging.impl.SimpleLog" - }; - - - // ----------------------------------------------------- Instance Variables - - /** - * Determines whether logging classes should be loaded using the thread-context - * classloader, or via the classloader that loaded this LogFactoryImpl class. - */ - private boolean useTCCL = true; - - /** - * The string prefixed to every message output by the logDiagnostic method. - */ - private String diagnosticPrefix; - - - /** - * Configuration attributes. - */ - protected Hashtable attributes = new Hashtable(); - - - /** - * The {@link org.apache.commons.logging.Log} instances that have - * already been created, keyed by logger name. - */ - protected Hashtable instances = new Hashtable(); - - - /** - * Name of the class implementing the Log interface. - */ - private String logClassName; - - - /** - * The one-argument constructor of the - * {@link org.apache.commons.logging.Log} - * implementation class that will be used to create new instances. - * This value is initialized by getLogConstructor(), - * and then returned repeatedly. - */ - protected Constructor logConstructor = null; - - - /** - * The signature of the Constructor to be used. - */ - protected Class logConstructorSignature[] = - { java.lang.String.class }; - - - /** - * The one-argument setLogFactory method of the selected - * {@link org.apache.commons.logging.Log} method, if it exists. - */ - protected Method logMethod = null; - - - /** - * The signature of the setLogFactory method to be used. - */ - protected Class logMethodSignature[] = - { LogFactory.class }; - - /** - * See getBaseClassLoader and initConfiguration. - */ - private boolean allowFlawedContext; - - /** - * See handleFlawedDiscovery and initConfiguration. - */ - private boolean allowFlawedDiscovery; - - /** - * See handleFlawedHierarchy and initConfiguration. - */ - private boolean allowFlawedHierarchy; - - // --------------------------------------------------------- Public Methods - - - /** - * Return the configuration attribute with the specified name (if any), - * or null if there is no such attribute. - * - * @param name Name of the attribute to return - */ - public Object getAttribute(String name) { - - return (attributes.get(name)); - - } - - - /** - * Return an array containing the names of all currently defined - * configuration attributes. If there are no such attributes, a zero - * length array is returned. - */ - public String[] getAttributeNames() { - - Vector names = new Vector(); - Enumeration keys = attributes.keys(); - while (keys.hasMoreElements()) { - names.addElement((String) keys.nextElement()); - } - String results[] = new String[names.size()]; - for (int i = 0; i < results.length; i++) { - results[i] = (String) names.elementAt(i); - } - return (results); - - } - - - /** - * Convenience method to derive a name from the specified class and - * call getInstance(String) with it. - * - * @param clazz Class for which a suitable Log name will be derived - * - * @exception LogConfigurationException if a suitable Log - * instance cannot be returned - */ - public Log getInstance(Class clazz) throws LogConfigurationException { - - return (getInstance(clazz.getName())); - - } - - - /** - *

Construct (if necessary) and return a Log instance, - * using the factory's current set of configuration attributes.

- * - *

NOTE - Depending upon the implementation of - * the LogFactory you are using, the Log - * instance you are returned may or may not be local to the current - * application, and may or may not be returned again on a subsequent - * call with the same name argument.

- * - * @param name Logical name of the Log instance to be - * returned (the meaning of this name is only known to the underlying - * logging implementation that is being wrapped) - * - * @exception LogConfigurationException if a suitable Log - * instance cannot be returned - */ - public Log getInstance(String name) throws LogConfigurationException { - - Log instance = (Log) instances.get(name); - if (instance == null) { - instance = newInstance(name); - instances.put(name, instance); - } - return (instance); - - } - - - /** - * Release any internal references to previously created - * {@link org.apache.commons.logging.Log} - * instances returned by this factory. This is useful in environments - * like servlet containers, which implement application reloading by - * throwing away a ClassLoader. Dangling references to objects in that - * class loader would prevent garbage collection. - */ - public void release() { - - logDiagnostic("Releasing all known loggers"); - instances.clear(); - } - - - /** - * Remove any configuration attribute associated with the specified name. - * If there is no such attribute, no action is taken. - * - * @param name Name of the attribute to remove - */ - public void removeAttribute(String name) { - - attributes.remove(name); - - } - - - /** - * Set the configuration attribute with the specified name. Calling - * this with a null value is equivalent to calling - * removeAttribute(name). - *

- * This method can be used to set logging configuration programmatically - * rather than via system properties. It can also be used in code running - * within a container (such as a webapp) to configure behaviour on a - * per-component level instead of globally as system properties would do. - * To use this method instead of a system property, call - *

-     * LogFactory.getFactory().setAttribute(...)
-     * 
- * This must be done before the first Log object is created; configuration - * changes after that point will be ignored. - *

- * This method is also called automatically if LogFactory detects a - * commons-logging.properties file; every entry in that file is set - * automatically as an attribute here. - * - * @param name Name of the attribute to set - * @param value Value of the attribute to set, or null - * to remove any setting for this attribute - */ - public void setAttribute(String name, Object value) { - - if (logConstructor != null) { - logDiagnostic("setAttribute: call too late; configuration already performed."); - } - - if (value == null) { - attributes.remove(name); - } else { - attributes.put(name, value); - } - - if (name.equals(TCCL_KEY)) { - useTCCL = Boolean.valueOf(value.toString()).booleanValue(); - } - - } - - - // ------------------------------------------------------ - // Static Methods - // - // These methods only defined as workarounds for a java 1.2 bug; - // theoretically none of these are needed. - // ------------------------------------------------------ - - /** - * Gets the context classloader. - * This method is a workaround for a java 1.2 compiler bug. - * @since 1.1 - */ - protected static ClassLoader getContextClassLoader() throws LogConfigurationException { - return LogFactory.getContextClassLoader(); - } - - - /** - * Workaround for bug in Java1.2; in theory this method is not needed. - * See LogFactory.isDiagnosticsEnabled. - */ - protected static boolean isDiagnosticsEnabled() { - return LogFactory.isDiagnosticsEnabled(); - } - - - /** - * Workaround for bug in Java1.2; in theory this method is not needed. - * See LogFactory.getClassLoader. - * @since 1.1 - */ - protected static ClassLoader getClassLoader(Class clazz) { - return LogFactory.getClassLoader(clazz); - } - - - // ------------------------------------------------------ Protected Methods - - /** - * Calculate and cache a string that uniquely identifies this instance, - * including which classloader the object was loaded from. - *

- * This string will later be prefixed to each "internal logging" message - * emitted, so that users can clearly see any unexpected behaviour. - *

- * Note that this method does not detect whether internal logging is - * enabled or not, nor where to output stuff if it is; that is all - * handled by the parent LogFactory class. This method just computes - * its own unique prefix for log messages. - */ - private void initDiagnostics() { - // It would be nice to include an identifier of the context classloader - // that this LogFactoryImpl object is responsible for. However that - // isn't possible as that information isn't available. It is possible - // to figure this out by looking at the logging from LogFactory to - // see the context & impl ids from when this object was instantiated, - // in order to link the impl id output as this object's prefix back to - // the context it is intended to manage. - // Note that this prefix should be kept consistent with that - // in LogFactory. - Class clazz = this.getClass(); - ClassLoader classLoader = getClassLoader(clazz); - String classLoaderName; - try { - if (classLoader == null) { - classLoaderName = "BOOTLOADER"; - } else { - classLoaderName = objectId(classLoader); - } - } catch(SecurityException e) { - classLoaderName = "UNKNOWN"; - } - diagnosticPrefix = "[LogFactoryImpl@" + System.identityHashCode(this) + " from " + classLoaderName + "] "; - } - - - /** - * Output a diagnostic message to a user-specified destination (if the - * user has enabled diagnostic logging). - * - * @param msg diagnostic message - * @since 1.1 - */ - protected void logDiagnostic(String msg) { - if (isDiagnosticsEnabled()) { - logRawDiagnostic(diagnosticPrefix + msg); - } - } - - /** - * Return the fully qualified Java classname of the {@link Log} - * implementation we will be using. - * - * @deprecated Never invoked by this class; subclasses should not assume - * it will be. - */ - protected String getLogClassName() { - - if (logClassName == null) { - discoverLogImplementation(getClass().getName()); - } - - return logClassName; - } - - - /** - *

Return the Constructor that can be called to instantiate - * new {@link org.apache.commons.logging.Log} instances.

- * - *

IMPLEMENTATION NOTE - Race conditions caused by - * calling this method from more than one thread are ignored, because - * the same Constructor instance will ultimately be derived - * in all circumstances.

- * - * @exception LogConfigurationException if a suitable constructor - * cannot be returned - * - * @deprecated Never invoked by this class; subclasses should not assume - * it will be. - */ - protected Constructor getLogConstructor() - throws LogConfigurationException { - - // Return the previously identified Constructor (if any) - if (logConstructor == null) { - discoverLogImplementation(getClass().getName()); - } - - return logConstructor; - } - - - /** - * Is JDK 1.3 with Lumberjack logging available? - * - * @deprecated Never invoked by this class; subclasses should not assume - * it will be. - */ - protected boolean isJdk13LumberjackAvailable() { - return isLogLibraryAvailable( - "Jdk13Lumberjack", - "org.apache.commons.logging.impl.Jdk13LumberjackLogger"); - } - - - /** - *

Return true if JDK 1.4 or later logging - * is available. Also checks that the Throwable class - * supports getStackTrace(), which is required by - * Jdk14Logger.

- * - * @deprecated Never invoked by this class; subclasses should not assume - * it will be. - */ - protected boolean isJdk14Available() { - return isLogLibraryAvailable( - "Jdk14", - "org.apache.commons.logging.impl.Jdk14Logger"); - } - - - /** - * Is a Log4J implementation available? - * - * @deprecated Never invoked by this class; subclasses should not assume - * it will be. - */ - protected boolean isLog4JAvailable() { - return isLogLibraryAvailable( - "Log4J", - LOGGING_IMPL_LOG4J_LOGGER); - } - - - /** - * Create and return a new {@link org.apache.commons.logging.Log} - * instance for the specified name. - * - * @param name Name of the new logger - * - * @exception LogConfigurationException if a new instance cannot - * be created - */ - protected Log newInstance(String name) throws LogConfigurationException { - - Log instance = null; - try { - if (logConstructor == null) { - instance = discoverLogImplementation(name); - } - else { - Object params[] = { name }; - instance = (Log) logConstructor.newInstance(params); - } - - if (logMethod != null) { - Object params[] = { this }; - logMethod.invoke(instance, params); - } - - return (instance); - - } catch (LogConfigurationException lce) { - - // this type of exception means there was a problem in discovery - // and we've already output diagnostics about the issue, etc.; - // just pass it on - throw (LogConfigurationException) lce; - - } catch (InvocationTargetException e) { - // A problem occurred invoking the Constructor or Method - // previously discovered - Throwable c = e.getTargetException(); - if (c != null) { - throw new LogConfigurationException(c); - } else { - throw new LogConfigurationException(e); - } - } catch (Throwable t) { - // A problem occurred invoking the Constructor or Method - // previously discovered - throw new LogConfigurationException(t); - } - } - - - // ------------------------------------------------------ Private Methods - - /** - * Calls LogFactory.directGetContextClassLoader under the control of an - * AccessController class. This means that java code running under a - * security manager that forbids access to ClassLoaders will still work - * if this class is given appropriate privileges, even when the caller - * doesn't have such privileges. Without using an AccessController, the - * the entire call stack must have the privilege before the call is - * allowed. - * - * @return the context classloader associated with the current thread, - * or null if security doesn't allow it. - * - * @throws LogConfigurationException if there was some weird error while - * attempting to get the context classloader. - * - * @throws SecurityException if the current java security policy doesn't - * allow this class to access the context classloader. - */ - private static ClassLoader getContextClassLoaderInternal() - throws LogConfigurationException { - return (ClassLoader)AccessController.doPrivileged( - new PrivilegedAction() { - public Object run() { - return LogFactory.directGetContextClassLoader(); - } - }); - } - - /** - * Read the specified system property, using an AccessController so that - * the property can be read if JCL has been granted the appropriate - * security rights even if the calling code has not. - *

- * Take care not to expose the value returned by this method to the - * calling application in any way; otherwise the calling app can use that - * info to access data that should not be available to it. - */ - private static String getSystemProperty(final String key, final String def) - throws SecurityException { - return (String) AccessController.doPrivileged( - new PrivilegedAction() { - public Object run() { - return System.getProperty(key, def); - } - }); - } - - /** - * Fetch the parent classloader of a specified classloader. - *

- * If a SecurityException occurs, null is returned. - *

- * Note that this method is non-static merely so logDiagnostic is available. - */ - private ClassLoader getParentClassLoader(final ClassLoader cl) { - try { - return (ClassLoader)AccessController.doPrivileged( - new PrivilegedAction() { - public Object run() { - return cl.getParent(); - } - }); - } catch(SecurityException ex) { - logDiagnostic("[SECURITY] Unable to obtain parent classloader"); - return null; - } - - } - - /** - * Utility method to check whether a particular logging library is - * present and available for use. Note that this does not - * affect the future behaviour of this class. - */ - private boolean isLogLibraryAvailable(String name, String classname) { - if (isDiagnosticsEnabled()) { - logDiagnostic("Checking for '" + name + "'."); - } - try { - Log log = createLogFromClass( - classname, - this.getClass().getName(), // dummy category - false); - - if (log == null) { - if (isDiagnosticsEnabled()) { - logDiagnostic("Did not find '" + name + "'."); - } - return false; - } else { - if (isDiagnosticsEnabled()) { - logDiagnostic("Found '" + name + "'."); - } - return true; - } - } catch(LogConfigurationException e) { - if (isDiagnosticsEnabled()) { - logDiagnostic("Logging system '" + name + "' is available but not useable."); - } - return false; - } - } - - /** - * Attempt to find an attribute (see method setAttribute) or a - * system property with the provided name and return its value. - *

- * The attributes associated with this object are checked before - * system properties in case someone has explicitly called setAttribute, - * or a configuration property has been set in a commons-logging.properties - * file. - * - * @return the value associated with the property, or null. - */ - private String getConfigurationValue(String property) { - if (isDiagnosticsEnabled()) { - logDiagnostic("[ENV] Trying to get configuration for item " + property); - } - - Object valueObj = getAttribute(property); - if (valueObj != null) { - if (isDiagnosticsEnabled()) { - logDiagnostic("[ENV] Found LogFactory attribute [" + valueObj + "] for " + property); - } - return valueObj.toString(); - } - - if (isDiagnosticsEnabled()) { - logDiagnostic("[ENV] No LogFactory attribute found for " + property); - } - - try { - // warning: minor security hole here, in that we potentially read a system - // property that the caller cannot, then output it in readable form as a - // diagnostic message. However it's only ever JCL-specific properties - // involved here, so the harm is truly trivial. - String value = getSystemProperty(property, null); - 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; (iStringBuffer 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 null - */ - 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 = getSystemProperty(LOG_PROPERTY, null); - } 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 = getSystemProperty(LOG_PROPERTY_OLD, null); - } 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 true if this object's state should - * be affected by this method call, false 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 - // 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(); - currentCL = getParentClassLoader(currentCL); - } - - if ((logAdapter != null) && affectState) { - // We've succeeded, so set instance fields - this.logClassName = logAdapterClassName; - this.logConstructor = constructor; - - // Identify the setLogFactory 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. - *

- * 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 and the allowFlawedContext option - * has been set then the classloader which loaded this class is returned - * instead. - *

- * 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 = getContextClassLoaderInternal(); - - 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. - *

- * @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 LogConfigurationException that wraps - * the passed Throwable. - * - * @param logAdapterClassName is the class name of the Log implementation - * that could not be instantiated. Cannot be null. - * - * @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 (discoveryFlaw instanceof InvocationTargetException ) { - // Ok, the lib is there but while trying to create a real underlying - // logger something failed in the underlying lib; display info about - // that if possible. - InvocationTargetException ite = (InvocationTargetException)discoveryFlaw; - Throwable cause = ite.getTargetException(); - if (cause != null) { - logDiagnostic("... InvocationTargetException: " + - cause.getClass().getName() + ": " + - cause.getLocalizedMessage()); - - if (cause instanceof ExceptionInInitializerError) { - ExceptionInInitializerError eiie = (ExceptionInInitializerError)cause; - Throwable cause2 = eiie.getException(); - if (cause2 != null) { - logDiagnostic("... ExceptionInInitializerError: " + - cause2.getClass().getName() + ": " + - cause2.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. - *

- * There are two possible reasons why we successfully loaded the - * specified log adapter class then failed to cast it to a Log object: - *

    - *
  1. the specific class just doesn't implement the Log interface - * (user screwed up), or - *
  2. the specified class has bound to a Log class loaded by some other - * classloader; Log@classloaderX cannot be cast to Log@classloaderY. - *
- *

- * 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()); - } - } - } -} diff --git a/java/src/org/apache/commons/logging/impl/LogKitLogger.java b/java/src/org/apache/commons/logging/impl/LogKitLogger.java deleted file mode 100644 index 5e6cf4b..0000000 --- a/java/src/org/apache/commons/logging/impl/LogKitLogger.java +++ /dev/null @@ -1,294 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - - -package org.apache.commons.logging.impl; - -import java.io.Serializable; -import org.apache.log.Logger; -import org.apache.log.Hierarchy; -import org.apache.commons.logging.Log; - -/** - *

Implementation of org.apache.commons.logging.Log - * that wraps the avalon-logkit - * logging system. Configuration of LogKit is left to the user. - *

- * - *

LogKit accepts only String messages. - * Therefore, this implementation converts object messages into strings - * by called their toString() method before logging them.

- * - * @author Scott Sanders - * @author Robert Burrell Donkin - * @version $Id: LogKitLogger.java 424107 2006-07-20 23:15:42Z skitching $ - */ - -public class LogKitLogger implements Log, Serializable { - - - // ------------------------------------------------------------- Attributes - - - /** Logging goes to this LogKit logger */ - protected transient Logger logger = null; - - /** Name of this logger */ - protected String name = null; - - - // ------------------------------------------------------------ Constructor - - - /** - * Construct LogKitLogger which wraps the LogKit - * logger with given name. - * - * @param name log name - */ - public LogKitLogger(String name) { - this.name = name; - this.logger = getLogger(); - } - - - // --------------------------------------------------------- Public Methods - - - /** - *

Return the underlying Logger we are using.

- */ - public Logger getLogger() { - - if (logger == null) { - logger = Hierarchy.getDefaultHierarchy().getLoggerFor(name); - } - return (logger); - - } - - - // ----------------------------------------------------- Log Implementation - - - /** - * Logs a message with org.apache.log.Priority.DEBUG. - * - * @param message to log - * @see org.apache.commons.logging.Log#trace(Object) - */ - public void trace(Object message) { - debug(message); - } - - - /** - * Logs a message with org.apache.log.Priority.DEBUG. - * - * @param message to log - * @param t log this cause - * @see org.apache.commons.logging.Log#trace(Object, Throwable) - */ - public void trace(Object message, Throwable t) { - debug(message, t); - } - - - /** - * Logs a message with org.apache.log.Priority.DEBUG. - * - * @param message to log - * @see org.apache.commons.logging.Log#debug(Object) - */ - public void debug(Object message) { - if (message != null) { - getLogger().debug(String.valueOf(message)); - } - } - - - /** - * Logs a message with org.apache.log.Priority.DEBUG. - * - * @param message to log - * @param t log this cause - * @see org.apache.commons.logging.Log#debug(Object, Throwable) - */ - public void debug(Object message, Throwable t) { - if (message != null) { - getLogger().debug(String.valueOf(message), t); - } - } - - - /** - * Logs a message with org.apache.log.Priority.INFO. - * - * @param message to log - * @see org.apache.commons.logging.Log#info(Object) - */ - public void info(Object message) { - if (message != null) { - getLogger().info(String.valueOf(message)); - } - } - - - /** - * Logs a message with org.apache.log.Priority.INFO. - * - * @param message to log - * @param t log this cause - * @see org.apache.commons.logging.Log#info(Object, Throwable) - */ - public void info(Object message, Throwable t) { - if (message != null) { - getLogger().info(String.valueOf(message), t); - } - } - - - /** - * Logs a message with org.apache.log.Priority.WARN. - * - * @param message to log - * @see org.apache.commons.logging.Log#warn(Object) - */ - public void warn(Object message) { - if (message != null) { - getLogger().warn(String.valueOf(message)); - } - } - - - /** - * Logs a message with org.apache.log.Priority.WARN. - * - * @param message to log - * @param t log this cause - * @see org.apache.commons.logging.Log#warn(Object, Throwable) - */ - public void warn(Object message, Throwable t) { - if (message != null) { - getLogger().warn(String.valueOf(message), t); - } - } - - - /** - * Logs a message with org.apache.log.Priority.ERROR. - * - * @param message to log - * @see org.apache.commons.logging.Log#error(Object) - */ - public void error(Object message) { - if (message != null) { - getLogger().error(String.valueOf(message)); - } - } - - - /** - * Logs a message with org.apache.log.Priority.ERROR. - * - * @param message to log - * @param t log this cause - * @see org.apache.commons.logging.Log#error(Object, Throwable) - */ - public void error(Object message, Throwable t) { - if (message != null) { - getLogger().error(String.valueOf(message), t); - } - } - - - /** - * Logs a message with org.apache.log.Priority.FATAL_ERROR. - * - * @param message to log - * @see org.apache.commons.logging.Log#fatal(Object) - */ - public void fatal(Object message) { - if (message != null) { - getLogger().fatalError(String.valueOf(message)); - } - } - - - /** - * Logs a message with org.apache.log.Priority.FATAL_ERROR. - * - * @param message to log - * @param t log this cause - * @see org.apache.commons.logging.Log#fatal(Object, Throwable) - */ - public void fatal(Object message, Throwable t) { - if (message != null) { - getLogger().fatalError(String.valueOf(message), t); - } - } - - - /** - * Checks whether the LogKit logger will log messages of priority DEBUG. - */ - public boolean isDebugEnabled() { - return getLogger().isDebugEnabled(); - } - - - /** - * Checks whether the LogKit logger will log messages of priority ERROR. - */ - public boolean isErrorEnabled() { - return getLogger().isErrorEnabled(); - } - - - /** - * Checks whether the LogKit logger will log messages of priority FATAL_ERROR. - */ - public boolean isFatalEnabled() { - return getLogger().isFatalErrorEnabled(); - } - - - /** - * Checks whether the LogKit logger will log messages of priority INFO. - */ - public boolean isInfoEnabled() { - return getLogger().isInfoEnabled(); - } - - - /** - * Checks whether the LogKit logger will log messages of priority DEBUG. - */ - public boolean isTraceEnabled() { - return getLogger().isDebugEnabled(); - } - - - /** - * Checks whether the LogKit logger will log messages of priority WARN. - */ - public boolean isWarnEnabled() { - return getLogger().isWarnEnabled(); - } - - -} diff --git a/java/src/org/apache/commons/logging/impl/NoOpLog.java b/java/src/org/apache/commons/logging/impl/NoOpLog.java deleted file mode 100644 index a66bd10..0000000 --- a/java/src/org/apache/commons/logging/impl/NoOpLog.java +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - - -package org.apache.commons.logging.impl; - - -import java.io.Serializable; -import org.apache.commons.logging.Log; - - -/** - *

Trivial implementation of Log that throws away all messages. No - * configurable system properties are supported.

- * - * @author Scott Sanders - * @author Rod Waldhoff - * @version $Id: NoOpLog.java 424107 2006-07-20 23:15:42Z skitching $ - */ -public class NoOpLog implements Log, Serializable { - - /** Convenience constructor */ - public NoOpLog() { } - /** Base constructor */ - public NoOpLog(String name) { } - /** Do nothing */ - public void trace(Object message) { } - /** Do nothing */ - public void trace(Object message, Throwable t) { } - /** Do nothing */ - public void debug(Object message) { } - /** Do nothing */ - public void debug(Object message, Throwable t) { } - /** Do nothing */ - public void info(Object message) { } - /** Do nothing */ - public void info(Object message, Throwable t) { } - /** Do nothing */ - public void warn(Object message) { } - /** Do nothing */ - public void warn(Object message, Throwable t) { } - /** Do nothing */ - public void error(Object message) { } - /** Do nothing */ - public void error(Object message, Throwable t) { } - /** Do nothing */ - public void fatal(Object message) { } - /** Do nothing */ - public void fatal(Object message, Throwable t) { } - - /** - * Debug is never enabled. - * - * @return false - */ - public final boolean isDebugEnabled() { return false; } - - /** - * Error is never enabled. - * - * @return false - */ - public final boolean isErrorEnabled() { return false; } - - /** - * Fatal is never enabled. - * - * @return false - */ - public final boolean isFatalEnabled() { return false; } - - /** - * Info is never enabled. - * - * @return false - */ - public final boolean isInfoEnabled() { return false; } - - /** - * Trace is never enabled. - * - * @return false - */ - public final boolean isTraceEnabled() { return false; } - - /** - * Warn is never enabled. - * - * @return false - */ - public final boolean isWarnEnabled() { return false; } - -} diff --git a/java/src/org/apache/commons/logging/impl/ServletContextCleaner.java b/java/src/org/apache/commons/logging/impl/ServletContextCleaner.java deleted file mode 100644 index 046bf7e..0000000 --- a/java/src/org/apache/commons/logging/impl/ServletContextCleaner.java +++ /dev/null @@ -1,138 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - - -package org.apache.commons.logging.impl; - -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; - -import javax.servlet.ServletContextEvent; -import javax.servlet.ServletContextListener; - -import org.apache.commons.logging.LogFactory; - - -/** - * This class is capable of receiving notifications about the undeployment of - * a webapp, and responds by ensuring that commons-logging releases all - * memory associated with the undeployed webapp. - *

- * In general, the WeakHashtable support added in commons-logging release 1.1 - * ensures that logging classes do not hold references that prevent an - * undeployed webapp's memory from being garbage-collected even when multiple - * copies of commons-logging are deployed via multiple classloaders (a - * situation that earlier versions had problems with). However there are - * some rare cases where the WeakHashtable approach does not work; in these - * situations specifying this class as a listener for the web application will - * ensure that all references held by commons-logging are fully released. - *

- * To use this class, configure the webapp deployment descriptor to call - * this class on webapp undeploy; the contextDestroyed method will tell - * every accessable LogFactory class that the entry in its map for the - * current webapp's context classloader should be cleared. - * - * @since 1.1 - */ - -public class ServletContextCleaner implements ServletContextListener { - - private Class[] RELEASE_SIGNATURE = {ClassLoader.class}; - - /** - * Invoked when a webapp is undeployed, this tells the LogFactory - * class to release any logging information related to the current - * contextClassloader. - */ - public void contextDestroyed(ServletContextEvent sce) { - ClassLoader tccl = Thread.currentThread().getContextClassLoader(); - - Object[] params = new Object[1]; - params[0] = tccl; - - // Walk up the tree of classloaders, finding all the available - // LogFactory classes and releasing any objects associated with - // the tccl (ie the webapp). - // - // When there is only one LogFactory in the classpath, and it - // is within the webapp being undeployed then there is no problem; - // garbage collection works fine. - // - // When there are multiple LogFactory classes in the classpath but - // parent-first classloading is used everywhere, this loop is really - // short. The first instance of LogFactory found will - // be the highest in the classpath, and then no more will be found. - // This is ok, as with this setup this will be the only LogFactory - // holding any data associated with the tccl being released. - // - // When there are multiple LogFactory classes in the classpath and - // child-first classloading is used in any classloader, then multiple - // LogFactory instances may hold info about this TCCL; whenever the - // webapp makes a call into a class loaded via an ancestor classloader - // and that class calls LogFactory the tccl gets registered in - // the LogFactory instance that is visible from the ancestor - // classloader. However the concrete logging library it points - // to is expected to have been loaded via the TCCL, so the - // underlying logging lib is only initialised/configured once. - // These references from ancestor LogFactory classes down to - // TCCL classloaders are held via weak references and so should - // be released but there are circumstances where they may not. - // Walking up the classloader ancestry ladder releasing - // the current tccl at each level tree, though, will definitely - // clear any problem references. - ClassLoader loader = tccl; - while (loader != null) { - // Load via the current loader. Note that if the class is not accessable - // via this loader, but is accessable via some ancestor then that class - // will be returned. - try { - Class logFactoryClass = loader.loadClass("org.apache.commons.logging.LogFactory"); - Method releaseMethod = logFactoryClass.getMethod("release", RELEASE_SIGNATURE); - releaseMethod.invoke(null, params); - loader = logFactoryClass.getClassLoader().getParent(); - } catch(ClassNotFoundException ex) { - // Neither the current classloader nor any of its ancestors could find - // the LogFactory class, so we can stop now. - loader = null; - } catch(NoSuchMethodException ex) { - // This is not expected; every version of JCL has this method - System.err.println("LogFactory instance found which does not support release method!"); - loader = null; - } catch(IllegalAccessException ex) { - // This is not expected; every ancestor class should be accessable - System.err.println("LogFactory instance found which is not accessable!"); - loader = null; - } catch(InvocationTargetException ex) { - // This is not expected - System.err.println("LogFactory instance release method failed!"); - loader = null; - } - } - - // Just to be sure, invoke release on the LogFactory that is visible from - // this ServletContextCleaner class too. This should already have been caught - // by the above loop but just in case... - LogFactory.release(tccl); - } - - /** - * Invoked when a webapp is deployed. Nothing needs to be done here. - */ - public void contextInitialized(ServletContextEvent sce) { - // do nothing - } -} diff --git a/java/src/org/apache/commons/logging/impl/SimpleLog.java b/java/src/org/apache/commons/logging/impl/SimpleLog.java deleted file mode 100644 index fe1a7c5..0000000 --- a/java/src/org/apache/commons/logging/impl/SimpleLog.java +++ /dev/null @@ -1,721 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - - -package org.apache.commons.logging.impl; - -import java.io.InputStream; -import java.io.Serializable; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.security.AccessController; -import java.security.PrivilegedAction; -import java.text.DateFormat; -import java.text.SimpleDateFormat; -import java.util.Date; -import java.util.Properties; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogConfigurationException; - -/** - *

Simple implementation of Log that sends all enabled log messages, - * for all defined loggers, to System.err. The following system properties - * are supported to configure the behavior of this logger:

- * - * - *

In addition to looking for system properties with the names specified - * above, this implementation also checks for a class loader resource named - * "simplelog.properties", and includes any matching definitions - * from this resource (if it exists).

- * - * @author Scott Sanders - * @author Rod Waldhoff - * @author Robert Burrell Donkin - * - * @version $Id: SimpleLog.java 581090 2007-10-01 22:01:06Z dennisl $ - */ -public class SimpleLog implements Log, Serializable { - - - // ------------------------------------------------------- Class Attributes - - /** All system properties used by SimpleLog start with this */ - static protected final String systemPrefix = - "org.apache.commons.logging.simplelog."; - - /** Properties loaded from simplelog.properties */ - static protected final Properties simpleLogProps = new Properties(); - - /** The default format to use when formating dates */ - static protected final String DEFAULT_DATE_TIME_FORMAT = - "yyyy/MM/dd HH:mm:ss:SSS zzz"; - - /** Include the instance name in the log message? */ - static protected boolean showLogName = false; - /** Include the short name ( last component ) of the logger in the log - * message. Defaults to true - otherwise we'll be lost in a flood of - * messages without knowing who sends them. - */ - static protected boolean showShortName = true; - /** Include the current time in the log message */ - static protected boolean showDateTime = false; - /** The date and time format to use in the log message */ - static protected String dateTimeFormat = DEFAULT_DATE_TIME_FORMAT; - - /** - * Used to format times. - *

- * Any code that accesses this object should first obtain a lock on it, - * ie use synchronized(dateFormatter); this requirement was introduced - * in 1.1.1 to fix an existing thread safety bug (SimpleDateFormat.format - * is not thread-safe). - */ - static protected DateFormat dateFormatter = null; - - // ---------------------------------------------------- Log Level Constants - - - /** "Trace" level logging. */ - public static final int LOG_LEVEL_TRACE = 1; - /** "Debug" level logging. */ - public static final int LOG_LEVEL_DEBUG = 2; - /** "Info" level logging. */ - public static final int LOG_LEVEL_INFO = 3; - /** "Warn" level logging. */ - public static final int LOG_LEVEL_WARN = 4; - /** "Error" level logging. */ - public static final int LOG_LEVEL_ERROR = 5; - /** "Fatal" level logging. */ - public static final int LOG_LEVEL_FATAL = 6; - - /** Enable all logging levels */ - public static final int LOG_LEVEL_ALL = (LOG_LEVEL_TRACE - 1); - - /** Enable no logging levels */ - public static final int LOG_LEVEL_OFF = (LOG_LEVEL_FATAL + 1); - - // ------------------------------------------------------------ Initializer - - private static String getStringProperty(String name) { - String prop = null; - try { - prop = System.getProperty(name); - } catch (SecurityException e) { - ; // Ignore - } - return (prop == null) ? simpleLogProps.getProperty(name) : prop; - } - - private static String getStringProperty(String name, String dephault) { - String prop = getStringProperty(name); - return (prop == null) ? dephault : prop; - } - - private static boolean getBooleanProperty(String name, boolean dephault) { - String prop = getStringProperty(name); - return (prop == null) ? dephault : "true".equalsIgnoreCase(prop); - } - - // Initialize class attributes. - // Load properties file, if found. - // Override with system properties. - static { - // Add props from the resource simplelog.properties - InputStream in = getResourceAsStream("simplelog.properties"); - if(null != in) { - try { - simpleLogProps.load(in); - in.close(); - } catch(java.io.IOException e) { - // ignored - } - } - - showLogName = getBooleanProperty( systemPrefix + "showlogname", showLogName); - showShortName = getBooleanProperty( systemPrefix + "showShortLogname", showShortName); - showDateTime = getBooleanProperty( systemPrefix + "showdatetime", showDateTime); - - if(showDateTime) { - dateTimeFormat = getStringProperty(systemPrefix + "dateTimeFormat", - dateTimeFormat); - try { - dateFormatter = new SimpleDateFormat(dateTimeFormat); - } catch(IllegalArgumentException e) { - // If the format pattern is invalid - use the default format - dateTimeFormat = DEFAULT_DATE_TIME_FORMAT; - dateFormatter = new SimpleDateFormat(dateTimeFormat); - } - } - } - - // ------------------------------------------------------------- Attributes - - /** The name of this simple log instance */ - protected String logName = null; - /** The current log level */ - protected int currentLogLevel; - /** The short name of this simple log instance */ - private String shortLogName = null; - - - // ------------------------------------------------------------ Constructor - - /** - * Construct a simple log with given name. - * - * @param name log name - */ - public SimpleLog(String name) { - - logName = name; - - // Set initial log level - // Used to be: set default log level to ERROR - // IMHO it should be lower, but at least info ( costin ). - setLevel(SimpleLog.LOG_LEVEL_INFO); - - // Set log level from properties - String lvl = getStringProperty(systemPrefix + "log." + logName); - int i = String.valueOf(name).lastIndexOf("."); - while(null == lvl && i > -1) { - name = name.substring(0,i); - lvl = getStringProperty(systemPrefix + "log." + name); - i = String.valueOf(name).lastIndexOf("."); - } - - if(null == lvl) { - lvl = getStringProperty(systemPrefix + "defaultlog"); - } - - if("all".equalsIgnoreCase(lvl)) { - setLevel(SimpleLog.LOG_LEVEL_ALL); - } else if("trace".equalsIgnoreCase(lvl)) { - setLevel(SimpleLog.LOG_LEVEL_TRACE); - } else if("debug".equalsIgnoreCase(lvl)) { - setLevel(SimpleLog.LOG_LEVEL_DEBUG); - } else if("info".equalsIgnoreCase(lvl)) { - setLevel(SimpleLog.LOG_LEVEL_INFO); - } else if("warn".equalsIgnoreCase(lvl)) { - setLevel(SimpleLog.LOG_LEVEL_WARN); - } else if("error".equalsIgnoreCase(lvl)) { - setLevel(SimpleLog.LOG_LEVEL_ERROR); - } else if("fatal".equalsIgnoreCase(lvl)) { - setLevel(SimpleLog.LOG_LEVEL_FATAL); - } else if("off".equalsIgnoreCase(lvl)) { - setLevel(SimpleLog.LOG_LEVEL_OFF); - } - - } - - - // -------------------------------------------------------- Properties - - /** - *

Set logging level.

- * - * @param currentLogLevel new logging level - */ - public void setLevel(int currentLogLevel) { - - this.currentLogLevel = currentLogLevel; - - } - - - /** - *

Get logging level.

- */ - public int getLevel() { - - return currentLogLevel; - } - - - // -------------------------------------------------------- Logging Methods - - - /** - *

Do the actual logging. - * This method assembles the message - * and then calls write() to cause it to be written.

- * - * @param type One of the LOG_LEVEL_XXX constants defining the log level - * @param message The message itself (typically a String) - * @param t The exception whose stack trace should be logged - */ - protected void log(int type, Object message, Throwable t) { - // Use a string buffer for better performance - StringBuffer buf = new StringBuffer(); - - // Append date-time if so configured - if(showDateTime) { - Date now = new Date(); - String dateText; - synchronized(dateFormatter) { - dateText = dateFormatter.format(now); - } - buf.append(dateText); - buf.append(" "); - } - - // Append a readable representation of the log level - switch(type) { - case SimpleLog.LOG_LEVEL_TRACE: buf.append("[TRACE] "); break; - case SimpleLog.LOG_LEVEL_DEBUG: buf.append("[DEBUG] "); break; - case SimpleLog.LOG_LEVEL_INFO: buf.append("[INFO] "); break; - case SimpleLog.LOG_LEVEL_WARN: buf.append("[WARN] "); break; - case SimpleLog.LOG_LEVEL_ERROR: buf.append("[ERROR] "); break; - case SimpleLog.LOG_LEVEL_FATAL: buf.append("[FATAL] "); break; - } - - // Append the name of the log instance if so configured - if( showShortName) { - if( shortLogName==null ) { - // Cut all but the last component of the name for both styles - shortLogName = logName.substring(logName.lastIndexOf(".") + 1); - shortLogName = - shortLogName.substring(shortLogName.lastIndexOf("/") + 1); - } - buf.append(String.valueOf(shortLogName)).append(" - "); - } else if(showLogName) { - buf.append(String.valueOf(logName)).append(" - "); - } - - // Append the message - buf.append(String.valueOf(message)); - - // Append stack trace if not null - if(t != null) { - buf.append(" <"); - buf.append(t.toString()); - buf.append(">"); - - java.io.StringWriter sw= new java.io.StringWriter(1024); - java.io.PrintWriter pw= new java.io.PrintWriter(sw); - t.printStackTrace(pw); - pw.close(); - buf.append(sw.toString()); - } - - // Print to the appropriate destination - write(buf); - - } - - - /** - *

Write the content of the message accumulated in the specified - * StringBuffer to the appropriate output destination. The - * default implementation writes to System.err.

- * - * @param buffer A StringBuffer containing the accumulated - * text to be logged - */ - protected void write(StringBuffer buffer) { - - System.err.println(buffer.toString()); - - } - - - /** - * Is the given log level currently enabled? - * - * @param logLevel is this level enabled? - */ - protected boolean isLevelEnabled(int logLevel) { - // log level are numerically ordered so can use simple numeric - // comparison - return (logLevel >= currentLogLevel); - } - - - // -------------------------------------------------------- Log Implementation - - - /** - * Logs a message with - * org.apache.commons.logging.impl.SimpleLog.LOG_LEVEL_DEBUG. - * - * @param message to log - * @see org.apache.commons.logging.Log#debug(Object) - */ - public final void debug(Object message) { - - if (isLevelEnabled(SimpleLog.LOG_LEVEL_DEBUG)) { - log(SimpleLog.LOG_LEVEL_DEBUG, message, null); - } - } - - - /** - * Logs a message with - * org.apache.commons.logging.impl.SimpleLog.LOG_LEVEL_DEBUG. - * - * @param message to log - * @param t log this cause - * @see org.apache.commons.logging.Log#debug(Object, Throwable) - */ - public final void debug(Object message, Throwable t) { - - if (isLevelEnabled(SimpleLog.LOG_LEVEL_DEBUG)) { - log(SimpleLog.LOG_LEVEL_DEBUG, message, t); - } - } - - - /** - * Logs a message with - * org.apache.commons.logging.impl.SimpleLog.LOG_LEVEL_TRACE. - * - * @param message to log - * @see org.apache.commons.logging.Log#trace(Object) - */ - public final void trace(Object message) { - - if (isLevelEnabled(SimpleLog.LOG_LEVEL_TRACE)) { - log(SimpleLog.LOG_LEVEL_TRACE, message, null); - } - } - - - /** - * Logs a message with - * org.apache.commons.logging.impl.SimpleLog.LOG_LEVEL_TRACE. - * - * @param message to log - * @param t log this cause - * @see org.apache.commons.logging.Log#trace(Object, Throwable) - */ - public final void trace(Object message, Throwable t) { - - if (isLevelEnabled(SimpleLog.LOG_LEVEL_TRACE)) { - log(SimpleLog.LOG_LEVEL_TRACE, message, t); - } - } - - - /** - * Logs a message with - * org.apache.commons.logging.impl.SimpleLog.LOG_LEVEL_INFO. - * - * @param message to log - * @see org.apache.commons.logging.Log#info(Object) - */ - public final void info(Object message) { - - if (isLevelEnabled(SimpleLog.LOG_LEVEL_INFO)) { - log(SimpleLog.LOG_LEVEL_INFO,message,null); - } - } - - - /** - * Logs a message with - * org.apache.commons.logging.impl.SimpleLog.LOG_LEVEL_INFO. - * - * @param message to log - * @param t log this cause - * @see org.apache.commons.logging.Log#info(Object, Throwable) - */ - public final void info(Object message, Throwable t) { - - if (isLevelEnabled(SimpleLog.LOG_LEVEL_INFO)) { - log(SimpleLog.LOG_LEVEL_INFO, message, t); - } - } - - - /** - * Logs a message with - * org.apache.commons.logging.impl.SimpleLog.LOG_LEVEL_WARN. - * - * @param message to log - * @see org.apache.commons.logging.Log#warn(Object) - */ - public final void warn(Object message) { - - if (isLevelEnabled(SimpleLog.LOG_LEVEL_WARN)) { - log(SimpleLog.LOG_LEVEL_WARN, message, null); - } - } - - - /** - * Logs a message with - * org.apache.commons.logging.impl.SimpleLog.LOG_LEVEL_WARN. - * - * @param message to log - * @param t log this cause - * @see org.apache.commons.logging.Log#warn(Object, Throwable) - */ - public final void warn(Object message, Throwable t) { - - if (isLevelEnabled(SimpleLog.LOG_LEVEL_WARN)) { - log(SimpleLog.LOG_LEVEL_WARN, message, t); - } - } - - - /** - * Logs a message with - * org.apache.commons.logging.impl.SimpleLog.LOG_LEVEL_ERROR. - * - * @param message to log - * @see org.apache.commons.logging.Log#error(Object) - */ - public final void error(Object message) { - - if (isLevelEnabled(SimpleLog.LOG_LEVEL_ERROR)) { - log(SimpleLog.LOG_LEVEL_ERROR, message, null); - } - } - - - /** - * Logs a message with - * org.apache.commons.logging.impl.SimpleLog.LOG_LEVEL_ERROR. - * - * @param message to log - * @param t log this cause - * @see org.apache.commons.logging.Log#error(Object, Throwable) - */ - public final void error(Object message, Throwable t) { - - if (isLevelEnabled(SimpleLog.LOG_LEVEL_ERROR)) { - log(SimpleLog.LOG_LEVEL_ERROR, message, t); - } - } - - - /** - * Log a message with - * org.apache.commons.logging.impl.SimpleLog.LOG_LEVEL_FATAL. - * - * @param message to log - * @see org.apache.commons.logging.Log#fatal(Object) - */ - public final void fatal(Object message) { - - if (isLevelEnabled(SimpleLog.LOG_LEVEL_FATAL)) { - log(SimpleLog.LOG_LEVEL_FATAL, message, null); - } - } - - - /** - * Logs a message with - * org.apache.commons.logging.impl.SimpleLog.LOG_LEVEL_FATAL. - * - * @param message to log - * @param t log this cause - * @see org.apache.commons.logging.Log#fatal(Object, Throwable) - */ - public final void fatal(Object message, Throwable t) { - - if (isLevelEnabled(SimpleLog.LOG_LEVEL_FATAL)) { - log(SimpleLog.LOG_LEVEL_FATAL, message, t); - } - } - - - /** - *

Are debug messages currently enabled?

- * - *

This allows expensive operations such as String - * concatenation to be avoided when the message will be ignored by the - * logger.

- */ - public final boolean isDebugEnabled() { - - return isLevelEnabled(SimpleLog.LOG_LEVEL_DEBUG); - } - - - /** - *

Are error messages currently enabled?

- * - *

This allows expensive operations such as String - * concatenation to be avoided when the message will be ignored by the - * logger.

- */ - public final boolean isErrorEnabled() { - - return isLevelEnabled(SimpleLog.LOG_LEVEL_ERROR); - } - - - /** - *

Are fatal messages currently enabled?

- * - *

This allows expensive operations such as String - * concatenation to be avoided when the message will be ignored by the - * logger.

- */ - public final boolean isFatalEnabled() { - - return isLevelEnabled(SimpleLog.LOG_LEVEL_FATAL); - } - - - /** - *

Are info messages currently enabled?

- * - *

This allows expensive operations such as String - * concatenation to be avoided when the message will be ignored by the - * logger.

- */ - public final boolean isInfoEnabled() { - - return isLevelEnabled(SimpleLog.LOG_LEVEL_INFO); - } - - - /** - *

Are trace messages currently enabled?

- * - *

This allows expensive operations such as String - * concatenation to be avoided when the message will be ignored by the - * logger.

- */ - public final boolean isTraceEnabled() { - - return isLevelEnabled(SimpleLog.LOG_LEVEL_TRACE); - } - - - /** - *

Are warn messages currently enabled?

- * - *

This allows expensive operations such as String - * concatenation to be avoided when the message will be ignored by the - * logger.

- */ - public final boolean isWarnEnabled() { - - return isLevelEnabled(SimpleLog.LOG_LEVEL_WARN); - } - - - /** - * Return the thread context class loader if available. - * Otherwise return null. - * - * The thread context class loader is available for JDK 1.2 - * or later, if certain security conditions are met. - * - * @exception LogConfigurationException if a suitable class loader - * cannot be identified. - */ - private static ClassLoader getContextClassLoader() - { - ClassLoader classLoader = null; - - if (classLoader == null) { - try { - // Are we running on a JDK 1.2 or later system? - Method method = Thread.class.getMethod("getContextClassLoader", - (Class[]) null); - - // Get the thread context class loader (if there is one) - try { - classLoader = (ClassLoader)method.invoke(Thread.currentThread(), - (Class[]) null); - } catch (IllegalAccessException e) { - ; // ignore - } catch (InvocationTargetException e) { - /** - * InvocationTargetException is thrown by 'invoke' when - * the method being invoked (getContextClassLoader) throws - * an exception. - * - * getContextClassLoader() throws SecurityException when - * the context class loader isn't an ancestor of the - * calling class's class loader, or if security - * permissions are restricted. - * - * In the first case (not related), we want to ignore and - * keep going. We cannot help but also ignore the second - * with the logic below, but other calls elsewhere (to - * obtain a class loader) will trigger this exception where - * we can make a distinction. - */ - if (e.getTargetException() instanceof SecurityException) { - ; // ignore - } else { - // Capture 'e.getTargetException()' exception for details - // alternate: log 'e.getTargetException()', and pass back 'e'. - throw new LogConfigurationException - ("Unexpected InvocationTargetException", e.getTargetException()); - } - } - } catch (NoSuchMethodException e) { - // Assume we are running on JDK 1.1 - ; // ignore - } - } - - if (classLoader == null) { - classLoader = SimpleLog.class.getClassLoader(); - } - - // Return the selected class loader - return classLoader; - } - - private static InputStream getResourceAsStream(final String name) - { - return (InputStream)AccessController.doPrivileged( - new PrivilegedAction() { - public Object run() { - ClassLoader threadCL = getContextClassLoader(); - - if (threadCL != null) { - return threadCL.getResourceAsStream(name); - } else { - return ClassLoader.getSystemResourceAsStream(name); - } - } - }); - } -} - diff --git a/java/src/org/apache/commons/logging/impl/WeakHashtable.java b/java/src/org/apache/commons/logging/impl/WeakHashtable.java deleted file mode 100644 index 3748ceb..0000000 --- a/java/src/org/apache/commons/logging/impl/WeakHashtable.java +++ /dev/null @@ -1,478 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - - -package org.apache.commons.logging.impl; - -import java.lang.ref.ReferenceQueue; -import java.lang.ref.WeakReference; -import java.util.*; - -/** - *

Implementation of Hashtable that uses WeakReference's - * to hold its keys thus allowing them to be reclaimed by the garbage collector. - * The associated values are retained using strong references.

- * - *

This class follows the symantics of Hashtable as closely as - * possible. It therefore does not accept null values or keys.

- * - *

Note: - * This is not intended to be a general purpose hash table replacement. - * This implementation is also tuned towards a particular purpose: for use as a replacement - * for Hashtable in LogFactory. This application requires - * good liveliness for get and put. Various tradeoffs - * have been made with this in mind. - *

- *

- * Usage: typical use case is as a drop-in replacement - * for the Hashtable used in LogFactory for J2EE enviroments - * running 1.3+ JVMs. Use of this class in most cases (see below) will - * allow classloaders to be collected by the garbage collector without the need - * to call {@link org.apache.commons.logging.LogFactory#release(ClassLoader) LogFactory.release(ClassLoader)}. - *

- * - *

org.apache.commons.logging.LogFactory checks whether this class - * can be supported by the current JVM, and if so then uses it to store - * references to the LogFactory implementationd it loads - * (rather than using a standard Hashtable instance). - * Having this class used instead of Hashtable solves - * certain issues related to dynamic reloading of applications in J2EE-style - * environments. However this class requires java 1.3 or later (due to its use - * of java.lang.ref.WeakReference and associates). - * And by the way, this extends Hashtable rather than HashMap - * for backwards compatibility reasons. See the documentation - * for method LogFactory.createFactoryStore for more details.

- * - *

The reason all this is necessary is due to a issue which - * arises during hot deploy in a J2EE-like containers. - * Each component running in the container owns one or more classloaders; when - * the component loads a LogFactory instance via the component classloader - * a reference to it gets stored in the static LogFactory.factories member, - * keyed by the component's classloader so different components don't - * stomp on each other. When the component is later unloaded, the container - * sets the component's classloader to null with the intent that all the - * component's classes get garbage-collected. However there's still a - * reference to the component's classloader from a key in the "global" - * LogFactory's factories member! If LogFactory.release() - * is called whenever component is unloaded, the classloaders will be correctly - * garbage collected; this should be done by any container that - * bundles commons-logging by default. However, holding the classloader - * references weakly ensures that the classloader will be garbage collected - * without the container performing this step.

- * - *

- * Limitations: - * There is still one (unusual) scenario in which a component will not - * be correctly unloaded without an explicit release. Though weak references - * are used for its keys, it is necessary to use strong references for its values. - *

- * - *

If the abstract class LogFactory is - * loaded by the container classloader but a subclass of - * LogFactory [LogFactory1] is loaded by the component's - * classloader and an instance stored in the static map associated with the - * base LogFactory class, then there is a strong reference from the LogFactory - * class to the LogFactory1 instance (as normal) and a strong reference from - * the LogFactory1 instance to the component classloader via - * getClass().getClassLoader(). This chain of references will prevent - * collection of the child classloader.

- * - *

- * Such a situation occurs when the commons-logging.jar is - * loaded by a parent classloader (e.g. a server level classloader in a - * servlet container) and a custom LogFactory implementation is - * loaded by a child classloader (e.g. a web app classloader).

- * - *

To avoid this scenario, ensure - * that any custom LogFactory subclass is loaded by the same classloader as - * the base LogFactory. Creating custom LogFactory subclasses is, - * however, rare. The standard LogFactoryImpl class should be sufficient - * for most or all users.

- * - * - * @author Brian Stansberry - * - * @since 1.1 - */ -public final class WeakHashtable extends Hashtable { - - /** - * The maximum number of times put() or remove() can be called before - * the map will be purged of all cleared entries. - */ - private static final int MAX_CHANGES_BEFORE_PURGE = 100; - - /** - * The maximum number of times put() or remove() can be called before - * the map will be purged of one cleared entry. - */ - private static final int PARTIAL_PURGE_COUNT = 10; - - /* ReferenceQueue we check for gc'd keys */ - private ReferenceQueue queue = new ReferenceQueue(); - /* Counter used to control how often we purge gc'd entries */ - private int changeCount = 0; - - /** - * Constructs a WeakHashtable with the Hashtable default - * capacity and load factor. - */ - public WeakHashtable() {} - - - /** - *@see Hashtable - */ - public boolean containsKey(Object key) { - // purge should not be required - Referenced referenced = new Referenced(key); - return super.containsKey(referenced); - } - - /** - *@see Hashtable - */ - public Enumeration elements() { - purge(); - return super.elements(); - } - - /** - *@see Hashtable - */ - public Set entrySet() { - purge(); - Set referencedEntries = super.entrySet(); - Set unreferencedEntries = new HashSet(); - for (Iterator it=referencedEntries.iterator(); it.hasNext();) { - Map.Entry entry = (Map.Entry) it.next(); - Referenced referencedKey = (Referenced) entry.getKey(); - Object key = referencedKey.getValue(); - Object value = entry.getValue(); - if (key != null) { - Entry dereferencedEntry = new Entry(key, value); - unreferencedEntries.add(dereferencedEntry); - } - } - return unreferencedEntries; - } - - /** - *@see Hashtable - */ - public Object get(Object key) { - // for performance reasons, no purge - Referenced referenceKey = new Referenced(key); - return super.get(referenceKey); - } - - /** - *@see Hashtable - */ - public Enumeration keys() { - purge(); - final Enumeration enumer = super.keys(); - return new Enumeration() { - public boolean hasMoreElements() { - return enumer.hasMoreElements(); - } - public Object nextElement() { - Referenced nextReference = (Referenced) enumer.nextElement(); - return nextReference.getValue(); - } - }; - } - - - /** - *@see Hashtable - */ - public Set keySet() { - purge(); - Set referencedKeys = super.keySet(); - Set unreferencedKeys = new HashSet(); - for (Iterator it=referencedKeys.iterator(); it.hasNext();) { - Referenced referenceKey = (Referenced) it.next(); - Object keyValue = referenceKey.getValue(); - if (keyValue != null) { - unreferencedKeys.add(keyValue); - } - } - return unreferencedKeys; - } - - /** - *@see Hashtable - */ - public Object put(Object key, Object value) { - // check for nulls, ensuring symantics match superclass - if (key == null) { - throw new NullPointerException("Null keys are not allowed"); - } - if (value == null) { - throw new NullPointerException("Null values are not allowed"); - } - - // for performance reasons, only purge every - // MAX_CHANGES_BEFORE_PURGE times - if (changeCount++ > MAX_CHANGES_BEFORE_PURGE) { - purge(); - changeCount = 0; - } - // do a partial purge more often - else if ((changeCount % PARTIAL_PURGE_COUNT) == 0) { - purgeOne(); - } - - Referenced keyRef = new Referenced(key, queue); - return super.put(keyRef, value); - } - - /** - *@see Hashtable - */ - public void putAll(Map t) { - if (t != null) { - Set entrySet = t.entrySet(); - for (Iterator it=entrySet.iterator(); it.hasNext();) { - Map.Entry entry = (Map.Entry) it.next(); - put(entry.getKey(), entry.getValue()); - } - } - } - - /** - *@see Hashtable - */ - public Collection values() { - purge(); - return super.values(); - } - - /** - *@see Hashtable - */ - public Object remove(Object key) { - // for performance reasons, only purge every - // MAX_CHANGES_BEFORE_PURGE times - if (changeCount++ > MAX_CHANGES_BEFORE_PURGE) { - purge(); - changeCount = 0; - } - // do a partial purge more often - else if ((changeCount % PARTIAL_PURGE_COUNT) == 0) { - purgeOne(); - } - return super.remove(new Referenced(key)); - } - - /** - *@see Hashtable - */ - public boolean isEmpty() { - purge(); - return super.isEmpty(); - } - - /** - *@see Hashtable - */ - public int size() { - purge(); - return super.size(); - } - - /** - *@see Hashtable - */ - public String toString() { - purge(); - return super.toString(); - } - - /** - * @see Hashtable - */ - protected void rehash() { - // purge here to save the effort of rehashing dead entries - purge(); - super.rehash(); - } - - /** - * Purges all entries whose wrapped keys - * have been garbage collected. - */ - private void purge() { - synchronized (queue) { - WeakKey key; - while ((key = (WeakKey) queue.poll()) != null) { - super.remove(key.getReferenced()); - } - } - } - - /** - * Purges one entry whose wrapped key - * has been garbage collected. - */ - private void purgeOne() { - - synchronized (queue) { - WeakKey key = (WeakKey) queue.poll(); - if (key != null) { - super.remove(key.getReferenced()); - } - } - } - - /** Entry implementation */ - private final static class Entry implements Map.Entry { - - private final Object key; - private final Object value; - - private Entry(Object key, Object value) { - this.key = key; - this.value = value; - } - - public boolean equals(Object o) { - boolean result = false; - if (o != null && o instanceof Map.Entry) { - Map.Entry entry = (Map.Entry) o; - result = (getKey()==null ? - entry.getKey() == null : - getKey().equals(entry.getKey())) - && - (getValue()==null ? - entry.getValue() == null : - getValue().equals(entry.getValue())); - } - return result; - } - - public int hashCode() { - - return (getKey()==null ? 0 : getKey().hashCode()) ^ - (getValue()==null ? 0 : getValue().hashCode()); - } - - public Object setValue(Object value) { - throw new UnsupportedOperationException("Entry.setValue is not supported."); - } - - public Object getValue() { - return value; - } - - public Object getKey() { - return key; - } - } - - - /** Wrapper giving correct symantics for equals and hashcode */ - private final static class Referenced { - - private final WeakReference reference; - private final int hashCode; - - /** - * - * @throws NullPointerException if referant is null - */ - private Referenced(Object referant) { - reference = new WeakReference(referant); - // Calc a permanent hashCode so calls to Hashtable.remove() - // work if the WeakReference has been cleared - hashCode = referant.hashCode(); - } - - /** - * - * @throws NullPointerException if key is null - */ - private Referenced(Object key, ReferenceQueue queue) { - reference = new WeakKey(key, queue, this); - // Calc a permanent hashCode so calls to Hashtable.remove() - // work if the WeakReference has been cleared - hashCode = key.hashCode(); - - } - - public int hashCode() { - return hashCode; - } - - private Object getValue() { - return reference.get(); - } - - public boolean equals(Object o) { - boolean result = false; - if (o instanceof Referenced) { - Referenced otherKey = (Referenced) o; - Object thisKeyValue = getValue(); - Object otherKeyValue = otherKey.getValue(); - if (thisKeyValue == null) { - result = (otherKeyValue == null); - - // Since our hashcode was calculated from the original - // non-null referant, the above check breaks the - // hashcode/equals contract, as two cleared Referenced - // objects could test equal but have different hashcodes. - // We can reduce (not eliminate) the chance of this - // happening by comparing hashcodes. - if (result == true) { - result = (this.hashCode() == otherKey.hashCode()); - } - // In any case, as our c'tor does not allow null referants - // and Hashtable does not do equality checks between - // existing keys, normal hashtable operations should never - // result in an equals comparison between null referants - } - else - { - result = thisKeyValue.equals(otherKeyValue); - } - } - return result; - } - } - - /** - * WeakReference subclass that holds a hard reference to an - * associated value and also makes accessible - * the Referenced object holding it. - */ - private final static class WeakKey extends WeakReference { - - private final Referenced referenced; - - private WeakKey(Object key, - ReferenceQueue queue, - Referenced referenced) { - super(key, queue); - this.referenced = referenced; - } - - private Referenced getReferenced() { - return referenced; - } - } -} diff --git a/java/src/org/apache/commons/logging/impl/package.html b/java/src/org/apache/commons/logging/impl/package.html deleted file mode 100644 index 0d37071..0000000 --- a/java/src/org/apache/commons/logging/impl/package.html +++ /dev/null @@ -1,22 +0,0 @@ - - - -

Concrete implementations of commons-logging wrapper APIs.

- diff --git a/java/src/org/apache/commons/logging/package.html b/java/src/org/apache/commons/logging/package.html deleted file mode 100644 index 6be8fd4..0000000 --- a/java/src/org/apache/commons/logging/package.html +++ /dev/null @@ -1,255 +0,0 @@ - - - -

Simple wrapper API around multiple logging APIs.

- - -

Overview

- -

This package provides an API for logging in server-based applications that -can be used around a variety of different logging implementations, including -prebuilt support for the following:

- - - -

Quick Start Guide

- -

For those impatient to just get on with it, the following example -illustrates the typical declaration and use of a logger that is named (by -convention) after the calling class: - -

-    import org.apache.commons.logging.Log;
-    import org.apache.commons.logging.LogFactory;
-
-    public class Foo {
-
-        private Log log = LogFactory.getLog(Foo.class);
-
-        public void foo() {
-            ...
-            try {
-                if (log.isDebugEnabled()) {
-                    log.debug("About to do something to object " + name);
-                }
-                name.bar();
-            } catch (IllegalStateException e) {
-                log.error("Something bad happened to " + name, e);
-            }
-            ...
-        }
-
- -

Unless you configure things differently, all log output will be written -to System.err. Therefore, you really will want to review the remainder of -this page in order to understand how to configure logging for your -application.

- - -

Configuring the Commons Logging Package

- - -

Choosing a LogFactory Implementation

- -

From an application perspective, the first requirement is to retrieve an -object reference to the LogFactory instance that will be used -to create Log instances for this -application. This is normally accomplished by calling the static -getFactory() method. This method implements the following -discovery algorithm to select the name of the LogFactory -implementation class this application wants to use:

- - -

If a commons-logging.properties file is found, all of the -properties defined there are also used to set configuration attributes on -the instantiated LogFactory instance.

- -

Once an implementation class name is selected, the corresponding class is -loaded from the current Thread context class loader (if there is one), or -from the class loader that loaded the LogFactory class itself -otherwise. This allows a copy of commons-logging.jar to be -shared in a multiple class loader environment (such as a servlet container), -but still allow each web application to provide its own LogFactory -implementation, if it so desires. An instance of this class will then be -created, and cached per class loader. - - -

The Default LogFactory Implementation

- -

The Logging Package APIs include a default LogFactory -implementation class ( -org.apache.commons.logging.impl.LogFactoryImpl) that is selected if no -other implementation class name can be discovered. Its primary purpose is -to create (as necessary) and return Log instances -in response to calls to the getInstance() method. The default -implementation uses the following rules:

- - -

See the SimpleLog JavaDocs for detailed -configuration information for this default implementation.

- - -

Configuring the Underlying Logging System

- -

The basic principle is that the user is totally responsible for the -configuration of the underlying logging system. -Commons-logging should not change the existing configuration.

- -

Each individual Log implementation may -support its own configuration properties. These will be documented in the -class descriptions for the corresponding implementation class.

- -

Finally, some Log implementations (such as the one for Log4J) -require an external configuration file for the entire logging environment. -This file should be prepared in a manner that is specific to the actual logging -technology being used.

- - -

Using the Logging Package APIs

- -

Use of the Logging Package APIs, from the perspective of an application -component, consists of the following steps:

-
    -
  1. Acquire a reference to an instance of - org.apache.commons.logging.Log, by calling the - factory method - - LogFactory.getInstance(String name). Your application can contain - references to multiple loggers that are used for different - purposes. A typical scenario for a server application is to have each - major component of the server use its own Log instance.
  2. -
  3. Cause messages to be logged (if the corresponding detail level is enabled) - by calling appropriate methods (trace(), debug(), - info(), warn(), error, and - fatal()).
  4. -
- -

For convenience, LogFactory also offers a static method -getLog() that combines the typical two-step pattern:

-
-  Log log = LogFactory.getFactory().getInstance(Foo.class);
-
-

into a single method call:

-
-  Log log = LogFactory.getLog(Foo.class);
-
- -

For example, you might use the following technique to initialize and -use a Log instance in an application component:

-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-public class MyComponent {
-
-  protected Log log =
-    LogFactory.getLog(MyComponent.class);
-
-  // Called once at startup time
-  public void start() {
-    ...
-    log.info("MyComponent started");
-    ...
-  }
-
-  // Called once at shutdown time
-  public void stop() {
-    ...
-    log.info("MyComponent stopped");
-    ...
-  }
-
-  // Called repeatedly to process a particular argument value
-  // which you want logged if debugging is enabled
-  public void process(String value) {
-    ...
-    // Do the string concatenation only if logging is enabled
-    if (log.isDebugEnabled())
-      log.debug("MyComponent processing " + value);
-    ...
-  }
-
-}
-
- -