1069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project/* 2069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Copyright 2001-2006 The Apache Software Foundation. 3069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 4069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 5069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * you may not use this file except in compliance with the License. 6069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * You may obtain a copy of the License at 7069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 8069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 9069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 10069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 11069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 12069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * See the License for the specific language governing permissions and 14069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * limitations under the License. 15069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 16069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 17069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectpackage org.apache.commons.logging; 18069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 19069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 20069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectimport java.io.BufferedReader; 21069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectimport java.io.FileOutputStream; 22069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectimport java.io.IOException; 23069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectimport java.io.InputStream; 24069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectimport java.io.InputStreamReader; 25069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectimport java.io.PrintStream; 26069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectimport java.lang.reflect.InvocationTargetException; 27069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectimport java.lang.reflect.Method; 28069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectimport java.net.URL; 29069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectimport java.security.AccessController; 30069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectimport java.security.PrivilegedAction; 31069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectimport java.util.Enumeration; 32069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectimport java.util.Hashtable; 33069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectimport java.util.Properties; 34069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 35069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 36069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project/** 37069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * <p>Factory for creating {@link Log} instances, with discovery and 38069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * configuration features similar to that employed by standard Java APIs 39069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * such as JAXP.</p> 40069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 41069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * <p><strong>IMPLEMENTATION NOTE</strong> - This implementation is heavily 42069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * based on the SAXParserFactory and DocumentBuilderFactory implementations 43069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * (corresponding to the JAXP pluggability APIs) found in Apache Xerces.</p> 44069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 45069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @author Craig R. McClanahan 46069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @author Costin Manolache 47069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @author Richard A. Sitze 48069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @version $Revision: 399431 $ $Date: 2006-05-03 21:58:34 +0100 (Wed, 03 May 2006) $ 49d42abb2fd917184764daf22f5f299e848b8701d7Narayan Kamath * 50d42abb2fd917184764daf22f5f299e848b8701d7Narayan Kamath * @deprecated Please use {@link java.net.URL#openConnection} instead. 51d42abb2fd917184764daf22f5f299e848b8701d7Narayan Kamath * Please visit <a href="http://android-developers.blogspot.com/2011/09/androids-http-clients.html">this webpage</a> 52d42abb2fd917184764daf22f5f299e848b8701d7Narayan Kamath * for further details. 53069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 54069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 55d42abb2fd917184764daf22f5f299e848b8701d7Narayan Kamath@Deprecated 56069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Projectpublic abstract class LogFactory { 57069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 58069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 59069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // ----------------------------------------------------- Manifest Constants 60069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 61069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 62069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * The name (<code>priority</code>) of the key in the config file used to 63069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * specify the priority of that particular config file. The associated value 64069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * is a floating-point number; higher values take priority over lower values. 65069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 66069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project public static final String PRIORITY_KEY = "priority"; 67069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 68069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 69069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * The name (<code>use_tccl</code>) of the key in the config file used 70069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * to specify whether logging classes should be loaded via the thread 71069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * context class loader (TCCL), or not. By default, the TCCL is used. 72069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 73069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project public static final String TCCL_KEY = "use_tccl"; 74069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 75069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 76069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * The name (<code>org.apache.commons.logging.LogFactory</code>) of the property 77069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * used to identify the LogFactory implementation 78069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * class name. This can be used as a system property, or as an entry in a 79069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * configuration properties file. 80069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 81069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project public static final String FACTORY_PROPERTY = 82069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project "org.apache.commons.logging.LogFactory"; 83069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 84069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 85069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * The fully qualified class name of the fallback <code>LogFactory</code> 86069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * implementation class to use, if no other can be found. 87069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 88069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project public static final String FACTORY_DEFAULT = 89069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project "org.apache.commons.logging.impl.LogFactoryImpl"; 90069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 91069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 92069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * The name (<code>commons-logging.properties</code>) of the properties file to search for. 93069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 94069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project public static final String FACTORY_PROPERTIES = 95069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project "commons-logging.properties"; 96069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 97069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 98069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * JDK1.3+ <a href="http://java.sun.com/j2se/1.3/docs/guide/jar/jar.html#Service%20Provider"> 99069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 'Service Provider' specification</a>. 100069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 101069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 102069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project protected static final String SERVICE_ID = 103069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project "META-INF/services/org.apache.commons.logging.LogFactory"; 104069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 105069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 106069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * The name (<code>org.apache.commons.logging.diagnostics.dest</code>) 107069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * of the property used to enable internal commons-logging 108069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * diagnostic output, in order to get information on what logging 109069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * implementations are being discovered, what classloaders they 110069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * are loaded through, etc. 111069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * <p> 112069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * If a system property of this name is set then the value is 113069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * assumed to be the name of a file. The special strings 114069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * STDOUT or STDERR (case-sensitive) indicate output to 115069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * System.out and System.err respectively. 116069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * <p> 117069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Diagnostic logging should be used only to debug problematic 118069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * configurations and should not be set in normal production use. 119069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 120069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project public static final String DIAGNOSTICS_DEST_PROPERTY = 121069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project "org.apache.commons.logging.diagnostics.dest"; 122069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 123069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 124069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * When null (the usual case), no diagnostic output will be 125069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * generated by LogFactory or LogFactoryImpl. When non-null, 126069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * interesting events will be written to the specified object. 127069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 128069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project private static PrintStream diagnosticsStream = null; 129069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 130069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 131069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * A string that gets prefixed to every message output by the 132069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * logDiagnostic method, so that users can clearly see which 133069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * LogFactory class is generating the output. 134069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 135069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project private static String diagnosticPrefix; 136069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 137069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 138069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * <p>Setting this system property 139069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * (<code>org.apache.commons.logging.LogFactory.HashtableImpl</code>) 140069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * value allows the <code>Hashtable</code> used to store 141069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * classloaders to be substituted by an alternative implementation. 142069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * </p> 143069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * <p> 144069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * <strong>Note:</strong> <code>LogFactory</code> will print: 145069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * <code><pre> 146069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * [ERROR] LogFactory: Load of custom hashtable failed</em> 147069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * </pre></code> 148069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * to system error and then continue using a standard Hashtable. 149069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * </p> 150069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * <p> 151069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * <strong>Usage:</strong> Set this property when Java is invoked 152069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * and <code>LogFactory</code> will attempt to load a new instance 153069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * of the given implementation class. 154069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * For example, running the following ant scriplet: 155069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * <code><pre> 156069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * <java classname="${test.runner}" fork="yes" failonerror="${test.failonerror}"> 157069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * ... 158069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * <sysproperty 159069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * key="org.apache.commons.logging.LogFactory.HashtableImpl" 160069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * value="org.apache.commons.logging.AltHashtable"/> 161069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * </java> 162069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * </pre></code> 163069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * will mean that <code>LogFactory</code> will load an instance of 164069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * <code>org.apache.commons.logging.AltHashtable</code>. 165069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * </p> 166069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * <p> 167069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * A typical use case is to allow a custom 168069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Hashtable implementation using weak references to be substituted. 169069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * This will allow classloaders to be garbage collected without 170069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * the need to release them (on 1.3+ JVMs only, of course ;) 171069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * </p> 172069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 173069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project public static final String HASHTABLE_IMPLEMENTATION_PROPERTY = 174069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project "org.apache.commons.logging.LogFactory.HashtableImpl"; 175069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** Name used to load the weak hashtable implementation by names */ 176069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project private static final String WEAK_HASHTABLE_CLASSNAME = 177069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project "org.apache.commons.logging.impl.WeakHashtable"; 178069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 179069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 180069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * A reference to the classloader that loaded this class. This is the 181069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * same as LogFactory.class.getClassLoader(). However computing this 182069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * value isn't quite as simple as that, as we potentially need to use 183069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * AccessControllers etc. It's more efficient to compute it once and 184069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * cache it here. 185069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 186069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project private static ClassLoader thisClassLoader; 187069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 188069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // ----------------------------------------------------------- Constructors 189069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 190069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 191069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 192069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Protected constructor that is not available for public use. 193069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 194069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project protected LogFactory() { 195069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 196069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 197069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // --------------------------------------------------------- Public Methods 198069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 199069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 200069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 201069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Return the configuration attribute with the specified name (if any), 202069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * or <code>null</code> if there is no such attribute. 203069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 204069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @param name Name of the attribute to return 205069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 206069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project public abstract Object getAttribute(String name); 207069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 208069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 209069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 210069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Return an array containing the names of all currently defined 211069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * configuration attributes. If there are no such attributes, a zero 212069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * length array is returned. 213069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 214069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project public abstract String[] getAttributeNames(); 215069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 216069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 217069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 218069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Convenience method to derive a name from the specified class and 219069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * call <code>getInstance(String)</code> with it. 220069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 221069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @param clazz Class for which a suitable Log name will be derived 222069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 223069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @exception LogConfigurationException if a suitable <code>Log</code> 224069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * instance cannot be returned 225069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 226069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project public abstract Log getInstance(Class clazz) 227069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project throws LogConfigurationException; 228069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 229069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 230069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 231069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * <p>Construct (if necessary) and return a <code>Log</code> instance, 232069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * using the factory's current set of configuration attributes.</p> 233069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 234069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * <p><strong>NOTE</strong> - Depending upon the implementation of 235069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * the <code>LogFactory</code> you are using, the <code>Log</code> 236069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * instance you are returned may or may not be local to the current 237069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * application, and may or may not be returned again on a subsequent 238069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * call with the same name argument.</p> 239069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 240069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @param name Logical name of the <code>Log</code> instance to be 241069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * returned (the meaning of this name is only known to the underlying 242069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * logging implementation that is being wrapped) 243069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 244069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @exception LogConfigurationException if a suitable <code>Log</code> 245069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * instance cannot be returned 246069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 247069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project public abstract Log getInstance(String name) 248069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project throws LogConfigurationException; 249069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 250069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 251069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 252069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Release any internal references to previously created {@link Log} 253069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * instances returned by this factory. This is useful in environments 254069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * like servlet containers, which implement application reloading by 255069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * throwing away a ClassLoader. Dangling references to objects in that 256069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * class loader would prevent garbage collection. 257069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 258069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project public abstract void release(); 259069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 260069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 261069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 262069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Remove any configuration attribute associated with the specified name. 263069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * If there is no such attribute, no action is taken. 264069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 265069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @param name Name of the attribute to remove 266069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 267069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project public abstract void removeAttribute(String name); 268069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 269069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 270069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 271069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Set the configuration attribute with the specified name. Calling 272069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * this with a <code>null</code> value is equivalent to calling 273069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * <code>removeAttribute(name)</code>. 274069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 275069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @param name Name of the attribute to set 276069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @param value Value of the attribute to set, or <code>null</code> 277069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * to remove any setting for this attribute 278069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 279069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project public abstract void setAttribute(String name, Object value); 280069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 281069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 282069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // ------------------------------------------------------- Static Variables 283069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 284069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 285069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 286069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * The previously constructed <code>LogFactory</code> instances, keyed by 287069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * the <code>ClassLoader</code> with which it was created. 288069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 289069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project protected static Hashtable factories = null; 290069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 291069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 292069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Prevously constructed <code>LogFactory</code> instance as in the 293069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * <code>factories</code> map, but for the case where 294069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * <code>getClassLoader</code> returns <code>null</code>. 295069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * This can happen when: 296069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * <ul> 297069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * <li>using JDK1.1 and the calling code is loaded via the system 298069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * classloader (very common)</li> 299069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * <li>using JDK1.2+ and the calling code is loaded via the boot 300069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * classloader (only likely for embedded systems work).</li> 301069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * </ul> 302069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Note that <code>factories</code> is a <i>Hashtable</i> (not a HashMap), 303069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * and hashtables don't allow null as a key. 304069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 305069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project protected static LogFactory nullClassLoaderFactory = null; 306069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 307069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 308069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Create the hashtable which will be used to store a map of 309069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * (context-classloader -> logfactory-object). Version 1.2+ of Java 310069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * supports "weak references", allowing a custom Hashtable class 311069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * to be used which uses only weak references to its keys. Using weak 312069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * references can fix memory leaks on webapp unload in some cases (though 313069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * not all). Version 1.1 of Java does not support weak references, so we 314069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * must dynamically determine which we are using. And just for fun, this 315069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * code also supports the ability for a system property to specify an 316069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * arbitrary Hashtable implementation name. 317069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * <p> 318069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Note that the correct way to ensure no memory leaks occur is to ensure 319069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * that LogFactory.release(contextClassLoader) is called whenever a 320069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * webapp is undeployed. 321069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 322069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project private static final Hashtable createFactoryStore() { 323069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project Hashtable result = null; 324069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project String storeImplementationClass 325069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project = System.getProperty(HASHTABLE_IMPLEMENTATION_PROPERTY); 326069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (storeImplementationClass == null) { 327069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project storeImplementationClass = WEAK_HASHTABLE_CLASSNAME; 328069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 329069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project try { 330069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project Class implementationClass = Class.forName(storeImplementationClass); 331069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project result = (Hashtable) implementationClass.newInstance(); 332069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 333069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } catch (Throwable t) { 334069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // ignore 335069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (!WEAK_HASHTABLE_CLASSNAME.equals(storeImplementationClass)) { 336069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // if the user's trying to set up a custom implementation, give a clue 337069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (isDiagnosticsEnabled()) { 338069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // use internal logging to issue the warning 339069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project logDiagnostic("[ERROR] LogFactory: Load of custom hashtable failed"); 340069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } else { 341069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // we *really* want this output, even if diagnostics weren't 342069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // explicitly enabled by the user. 343069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project System.err.println("[ERROR] LogFactory: Load of custom hashtable failed"); 344069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 345069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 346069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 347069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (result == null) { 348069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project result = new Hashtable(); 349069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 350069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project return result; 351069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 352069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 353069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 354069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // --------------------------------------------------------- Static Methods 355069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 356069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 357069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * <p>Construct (if necessary) and return a <code>LogFactory</code> 358069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * instance, using the following ordered lookup procedure to determine 359069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * the name of the implementation class to be loaded.</p> 360069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * <ul> 361069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * <li>The <code>org.apache.commons.logging.LogFactory</code> system 362069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * property.</li> 363069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * <li>The JDK 1.3 Service Discovery mechanism</li> 364069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * <li>Use the properties file <code>commons-logging.properties</code> 365069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * file, if found in the class path of this class. The configuration 366069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * file is in standard <code>java.util.Properties</code> format and 367069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * contains the fully qualified name of the implementation class 368069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * with the key being the system property defined above.</li> 369069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * <li>Fall back to a default implementation class 370069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * (<code>org.apache.commons.logging.impl.LogFactoryImpl</code>).</li> 371069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * </ul> 372069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 373069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * <p><em>NOTE</em> - If the properties file method of identifying the 374069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * <code>LogFactory</code> implementation class is utilized, all of the 375069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * properties defined in this file will be set as configuration attributes 376069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * on the corresponding <code>LogFactory</code> instance.</p> 377069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 378069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * <p><em>NOTE</em> - In a multithreaded environment it is possible 379069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * that two different instances will be returned for the same 380069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * classloader environment. 381069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * </p> 382069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 383069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @exception LogConfigurationException if the implementation class is not 384069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * available or cannot be instantiated. 385069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 386069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project public static LogFactory getFactory() throws LogConfigurationException { 387069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // Identify the class loader we will be using 388069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project ClassLoader contextClassLoader = getContextClassLoader(); 389069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 390069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (contextClassLoader == null) { 391069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // This is an odd enough situation to report about. This 392069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // output will be a nuisance on JDK1.1, as the system 393069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // classloader is null in that environment. 394069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (isDiagnosticsEnabled()) { 395069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project logDiagnostic("Context classloader is null."); 396069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 397069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 398069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 399069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // Return any previously registered factory for this class loader 400069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project LogFactory factory = getCachedFactory(contextClassLoader); 401069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (factory != null) { 402069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project return factory; 403069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 404069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 405069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (isDiagnosticsEnabled()) { 406069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project logDiagnostic( 407069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project "[LOOKUP] LogFactory implementation requested for the first time for context classloader " 408069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project + objectId(contextClassLoader)); 409069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project logHierarchy("[LOOKUP] ", contextClassLoader); 410069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 411069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 412069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // Load properties file. 413069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // 414069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // If the properties file exists, then its contents are used as 415069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // "attributes" on the LogFactory implementation class. One particular 416069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // property may also control which LogFactory concrete subclass is 417069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // used, but only if other discovery mechanisms fail.. 418069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // 419069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // As the properties file (if it exists) will be used one way or 420069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // another in the end we may as well look for it first. 421069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 422069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project Properties props = getConfigurationFile(contextClassLoader, FACTORY_PROPERTIES); 423069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 424069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // Determine whether we will be using the thread context class loader to 425069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // load logging classes or not by checking the loaded properties file (if any). 426069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project ClassLoader baseClassLoader = contextClassLoader; 427069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (props != null) { 428069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project String useTCCLStr = props.getProperty(TCCL_KEY); 429069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (useTCCLStr != null) { 430069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // The Boolean.valueOf(useTCCLStr).booleanValue() formulation 431069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // is required for Java 1.2 compatability. 432069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (Boolean.valueOf(useTCCLStr).booleanValue() == false) { 433069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // Don't use current context classloader when locating any 434069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // LogFactory or Log classes, just use the class that loaded 435069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // this abstract class. When this class is deployed in a shared 436069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // classpath of a container, it means webapps cannot deploy their 437069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // own logging implementations. It also means that it is up to the 438069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // implementation whether to load library-specific config files 439069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // from the TCCL or not. 440069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project baseClassLoader = thisClassLoader; 441069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 442069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 443069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 444069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 445069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // Determine which concrete LogFactory subclass to use. 446069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // First, try a global system property 447069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (isDiagnosticsEnabled()) { 448069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project logDiagnostic( 449069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project "[LOOKUP] Looking for system property [" + FACTORY_PROPERTY 450069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project + "] to define the LogFactory subclass to use..."); 451069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 452069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 453069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project try { 454069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project String factoryClass = System.getProperty(FACTORY_PROPERTY); 455069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (factoryClass != null) { 456069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (isDiagnosticsEnabled()) { 457069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project logDiagnostic( 458069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project "[LOOKUP] Creating an instance of LogFactory class '" + factoryClass 459069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project + "' as specified by system property " + FACTORY_PROPERTY); 460069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 461069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 462069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project factory = newFactory(factoryClass, baseClassLoader, contextClassLoader); 463069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } else { 464069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (isDiagnosticsEnabled()) { 465069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project logDiagnostic( 466069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project "[LOOKUP] No system property [" + FACTORY_PROPERTY 467069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project + "] defined."); 468069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 469069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 470069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } catch (SecurityException e) { 471069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (isDiagnosticsEnabled()) { 472069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project logDiagnostic( 473069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project "[LOOKUP] A security exception occurred while trying to create an" 474069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project + " instance of the custom factory class" 475069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project + ": [" + e.getMessage().trim() 476069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project + "]. Trying alternative implementations..."); 477069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 478069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project ; // ignore 479069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } catch(RuntimeException e) { 480069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // This is not consistent with the behaviour when a bad LogFactory class is 481069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // specified in a services file. 482069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // 483069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // One possible exception that can occur here is a ClassCastException when 484069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // the specified class wasn't castable to this LogFactory type. 485069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (isDiagnosticsEnabled()) { 486069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project logDiagnostic( 487069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project "[LOOKUP] An exception occurred while trying to create an" 488069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project + " instance of the custom factory class" 489069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project + ": [" + e.getMessage().trim() 490069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project + "] as specified by a system property."); 491069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 492069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project throw e; 493069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 494069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 495069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 496069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // Second, try to find a service by using the JDK1.3 class 497069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // discovery mechanism, which involves putting a file with the name 498069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // of an interface class in the META-INF/services directory, where the 499069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // contents of the file is a single line specifying a concrete class 500069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // that implements the desired interface. 501069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 502069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (factory == null) { 503069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (isDiagnosticsEnabled()) { 504069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project logDiagnostic( 505069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project "[LOOKUP] Looking for a resource file of name [" + SERVICE_ID 506069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project + "] to define the LogFactory subclass to use..."); 507069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 508069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project try { 509069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project InputStream is = getResourceAsStream(contextClassLoader, 510069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project SERVICE_ID); 511069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 512069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if( is != null ) { 513069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // This code is needed by EBCDIC and other strange systems. 514069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // It's a fix for bugs reported in xerces 515069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project BufferedReader rd; 516069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project try { 517069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project rd = new BufferedReader(new InputStreamReader(is, "UTF-8")); 518069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } catch (java.io.UnsupportedEncodingException e) { 519069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project rd = new BufferedReader(new InputStreamReader(is)); 520069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 521069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 522069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project String factoryClassName = rd.readLine(); 523069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project rd.close(); 524069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 525069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (factoryClassName != null && 526069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project ! "".equals(factoryClassName)) { 527069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (isDiagnosticsEnabled()) { 528069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project logDiagnostic( 529069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project "[LOOKUP] Creating an instance of LogFactory class " + factoryClassName 530069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project + " as specified by file '" + SERVICE_ID 531069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project + "' which was present in the path of the context" 532069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project + " classloader."); 533069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 534069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project factory = newFactory(factoryClassName, baseClassLoader, contextClassLoader ); 535069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 536069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } else { 537069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // is == null 538069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (isDiagnosticsEnabled()) { 539069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project logDiagnostic( 540069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project "[LOOKUP] No resource file with name '" + SERVICE_ID 541069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project + "' found."); 542069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 543069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 544069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } catch( Exception ex ) { 545069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // note: if the specified LogFactory class wasn't compatible with LogFactory 546069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // for some reason, a ClassCastException will be caught here, and attempts will 547069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // continue to find a compatible class. 548069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (isDiagnosticsEnabled()) { 549069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project logDiagnostic( 550069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project "[LOOKUP] A security exception occurred while trying to create an" 551069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project + " instance of the custom factory class" 552069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project + ": [" + ex.getMessage().trim() 553069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project + "]. Trying alternative implementations..."); 554069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 555069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project ; // ignore 556069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 557069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 558069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 559069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 560069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // Third try looking into the properties file read earlier (if found) 561069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 562069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (factory == null) { 563069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (props != null) { 564069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (isDiagnosticsEnabled()) { 565069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project logDiagnostic( 566069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project "[LOOKUP] Looking in properties file for entry with key '" 567069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project + FACTORY_PROPERTY 568069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project + "' to define the LogFactory subclass to use..."); 569069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 570069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project String factoryClass = props.getProperty(FACTORY_PROPERTY); 571069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (factoryClass != null) { 572069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (isDiagnosticsEnabled()) { 573069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project logDiagnostic( 574069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project "[LOOKUP] Properties file specifies LogFactory subclass '" 575069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project + factoryClass + "'"); 576069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 577069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project factory = newFactory(factoryClass, baseClassLoader, contextClassLoader); 578069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 579069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // TODO: think about whether we need to handle exceptions from newFactory 580069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } else { 581069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (isDiagnosticsEnabled()) { 582069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project logDiagnostic( 583069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project "[LOOKUP] Properties file has no entry specifying LogFactory subclass."); 584069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 585069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 586069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } else { 587069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (isDiagnosticsEnabled()) { 588069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project logDiagnostic( 589069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project "[LOOKUP] No properties file available to determine" 590069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project + " LogFactory subclass from.."); 591069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 592069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 593069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 594069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 595069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 596069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // Fourth, try the fallback implementation class 597069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 598069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (factory == null) { 599069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (isDiagnosticsEnabled()) { 600069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project logDiagnostic( 601069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project "[LOOKUP] Loading the default LogFactory implementation '" + FACTORY_DEFAULT 602069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project + "' via the same classloader that loaded this LogFactory" 603069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project + " class (ie not looking in the context classloader)."); 604069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 605069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 606069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // Note: unlike the above code which can try to load custom LogFactory 607069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // implementations via the TCCL, we don't try to load the default LogFactory 608069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // implementation via the context classloader because: 609069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // * that can cause problems (see comments in newFactory method) 610069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // * no-one should be customising the code of the default class 611069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // Yes, we do give up the ability for the child to ship a newer 612069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // version of the LogFactoryImpl class and have it used dynamically 613069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // by an old LogFactory class in the parent, but that isn't 614069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // necessarily a good idea anyway. 615069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project factory = newFactory(FACTORY_DEFAULT, thisClassLoader, contextClassLoader); 616069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 617069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 618069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (factory != null) { 619069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 620069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Always cache using context class loader. 621069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 622069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project cacheFactory(contextClassLoader, factory); 623069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 624069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if( props!=null ) { 625069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project Enumeration names = props.propertyNames(); 626069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project while (names.hasMoreElements()) { 627069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project String name = (String) names.nextElement(); 628069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project String value = props.getProperty(name); 629069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project factory.setAttribute(name, value); 630069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 631069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 632069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 633069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 634069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project return factory; 635069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 636069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 637069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 638069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 639069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Convenience method to return a named logger, without the application 640069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * having to care about factories. 641069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 642069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @param clazz Class from which a log name will be derived 643069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 644069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @exception LogConfigurationException if a suitable <code>Log</code> 645069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * instance cannot be returned 646069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 647069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project public static Log getLog(Class clazz) 648069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project throws LogConfigurationException { 649069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 650069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // BEGIN android-added 651069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project return getLog(clazz.getName()); 652069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // END android-added 653069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // BEGIN android-deleted 654069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project //return (getFactory().getInstance(clazz)); 655069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // END android-deleted 656069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 657069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 658069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 659069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 660069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 661069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Convenience method to return a named logger, without the application 662069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * having to care about factories. 663069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 664069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @param name Logical name of the <code>Log</code> instance to be 665069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * returned (the meaning of this name is only known to the underlying 666069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * logging implementation that is being wrapped) 667069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 668069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @exception LogConfigurationException if a suitable <code>Log</code> 669069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * instance cannot be returned 670069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 671069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project public static Log getLog(String name) 672069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project throws LogConfigurationException { 673069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 674069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // BEGIN android-added 675069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project return new org.apache.commons.logging.impl.Jdk14Logger(name); 676069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // END android-added 677069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // BEGIN android-deleted 678069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project //return (getFactory().getInstance(name)); 679069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // END android-deleted 680069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 681069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 682069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 683069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 684069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 685069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Release any internal references to previously created {@link LogFactory} 686069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * instances that have been associated with the specified class loader 687069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * (if any), after calling the instance method <code>release()</code> on 688069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * each of them. 689069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 690069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @param classLoader ClassLoader for which to release the LogFactory 691069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 692069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project public static void release(ClassLoader classLoader) { 693069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 694069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (isDiagnosticsEnabled()) { 695069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project logDiagnostic("Releasing factory for classloader " + objectId(classLoader)); 696069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 697069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project synchronized (factories) { 698069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (classLoader == null) { 699069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (nullClassLoaderFactory != null) { 700069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project nullClassLoaderFactory.release(); 701069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project nullClassLoaderFactory = null; 702069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 703069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } else { 704069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project LogFactory factory = (LogFactory) factories.get(classLoader); 705069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (factory != null) { 706069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project factory.release(); 707069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project factories.remove(classLoader); 708069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 709069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 710069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 711069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 712069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 713069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 714069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 715069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 716069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Release any internal references to previously created {@link LogFactory} 717069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * instances, after calling the instance method <code>release()</code> on 718069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * each of them. This is useful in environments like servlet containers, 719069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * which implement application reloading by throwing away a ClassLoader. 720069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Dangling references to objects in that class loader would prevent 721069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * garbage collection. 722069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 723069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project public static void releaseAll() { 724069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 725069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (isDiagnosticsEnabled()) { 726069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project logDiagnostic("Releasing factory for all classloaders."); 727069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 728069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project synchronized (factories) { 729069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project Enumeration elements = factories.elements(); 730069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project while (elements.hasMoreElements()) { 731069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project LogFactory element = (LogFactory) elements.nextElement(); 732069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project element.release(); 733069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 734069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project factories.clear(); 735069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 736069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (nullClassLoaderFactory != null) { 737069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project nullClassLoaderFactory.release(); 738069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project nullClassLoaderFactory = null; 739069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 740069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 741069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 742069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 743069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 744069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 745069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // ------------------------------------------------------ Protected Methods 746069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 747069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 748069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Safely get access to the classloader for the specified class. 749069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * <p> 750069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Theoretically, calling getClassLoader can throw a security exception, 751069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * and so should be done under an AccessController in order to provide 752069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * maximum flexibility. However in practice people don't appear to use 753069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * security policies that forbid getClassLoader calls. So for the moment 754069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * all code is written to call this method rather than Class.getClassLoader, 755069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * so that we could put AccessController stuff in this method without any 756069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * disruption later if we need to. 757069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * <p> 758069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Even when using an AccessController, however, this method can still 759069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * throw SecurityException. Commons-logging basically relies on the 760069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * ability to access classloaders, ie a policy that forbids all 761069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * classloader access will also prevent commons-logging from working: 762069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * currently this method will throw an exception preventing the entire app 763069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * from starting up. Maybe it would be good to detect this situation and 764069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * just disable all commons-logging? Not high priority though - as stated 765069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * above, security policies that prevent classloader access aren't common. 766069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 767069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @since 1.1 768069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 769069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project protected static ClassLoader getClassLoader(Class clazz) { 770069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project try { 771069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project return clazz.getClassLoader(); 772069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } catch(SecurityException ex) { 773069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (isDiagnosticsEnabled()) { 774069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project logDiagnostic( 775069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project "Unable to get classloader for class '" + clazz 776069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project + "' due to security restrictions - " + ex.getMessage()); 777069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 778069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project throw ex; 779069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 780069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 781069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 782069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 783069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Calls LogFactory.directGetContextClassLoader under the control of an 784069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * AccessController class. This means that java code running under a 785069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * security manager that forbids access to ClassLoaders will still work 786069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * if this class is given appropriate privileges, even when the caller 787069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * doesn't have such privileges. Without using an AccessController, the 788069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * the entire call stack must have the privilege before the call is 789069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * allowed. 790069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 791069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @return the context classloader associated with the current thread, 792069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * or null if security doesn't allow it. 793069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 794069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @throws LogConfigurationException if there was some weird error while 795069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * attempting to get the context classloader. 796069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 797069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @throws SecurityException if the current java security policy doesn't 798069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * allow this class to access the context classloader. 799069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 800069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project protected static ClassLoader getContextClassLoader() 801069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project throws LogConfigurationException { 802069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 803069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project return (ClassLoader)AccessController.doPrivileged( 804069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project new PrivilegedAction() { 805069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project public Object run() { 806069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project return directGetContextClassLoader(); 807069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 808069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project }); 809069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 810069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 811069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 812069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Return the thread context class loader if available; otherwise return 813069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * null. 814069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * <p> 815069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Most/all code should call getContextClassLoader rather than calling 816069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * this method directly. 817069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * <p> 818069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * The thread context class loader is available for JDK 1.2 819069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * or later, if certain security conditions are met. 820069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * <p> 821069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Note that no internal logging is done within this method because 822069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * this method is called every time LogFactory.getLogger() is called, 823069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * and we don't want too much output generated here. 824069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 825069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @exception LogConfigurationException if a suitable class loader 826069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * cannot be identified. 827069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 828069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @exception SecurityException if the java security policy forbids 829069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * access to the context classloader from one of the classes in the 830069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * current call stack. 831069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @since 1.1 832069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 833069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project protected static ClassLoader directGetContextClassLoader() 834069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project throws LogConfigurationException 835069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project { 836069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project ClassLoader classLoader = null; 837069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 838069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project try { 839069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // Are we running on a JDK 1.2 or later system? 840069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project Method method = Thread.class.getMethod("getContextClassLoader", 841069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project (Class[]) null); 842069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 843069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // Get the thread context class loader (if there is one) 844069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project try { 845069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project classLoader = (ClassLoader)method.invoke(Thread.currentThread(), 846069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project (Object[]) null); 847069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } catch (IllegalAccessException e) { 848069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project throw new LogConfigurationException 849069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project ("Unexpected IllegalAccessException", e); 850069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } catch (InvocationTargetException e) { 851069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 852069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * InvocationTargetException is thrown by 'invoke' when 853069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * the method being invoked (getContextClassLoader) throws 854069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * an exception. 855069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 856069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * getContextClassLoader() throws SecurityException when 857069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * the context class loader isn't an ancestor of the 858069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * calling class's class loader, or if security 859069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * permissions are restricted. 860069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 861069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * In the first case (not related), we want to ignore and 862069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * keep going. We cannot help but also ignore the second 863069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * with the logic below, but other calls elsewhere (to 864069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * obtain a class loader) will trigger this exception where 865069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * we can make a distinction. 866069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 867069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (e.getTargetException() instanceof SecurityException) { 868069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project ; // ignore 869069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } else { 870069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // Capture 'e.getTargetException()' exception for details 871069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // alternate: log 'e.getTargetException()', and pass back 'e'. 872069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project throw new LogConfigurationException 873069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project ("Unexpected InvocationTargetException", e.getTargetException()); 874069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 875069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 876069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } catch (NoSuchMethodException e) { 877069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // Assume we are running on JDK 1.1 878069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project classLoader = getClassLoader(LogFactory.class); 879069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 880069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // We deliberately don't log a message here to outputStream; 881069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // this message would be output for every call to LogFactory.getLog() 882069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // when running on JDK1.1 883069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // 884069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // if (outputStream != null) { 885069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // outputStream.println( 886069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // "Method Thread.getContextClassLoader does not exist;" 887069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // + " assuming this is JDK 1.1, and that the context" 888069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // + " classloader is the same as the class that loaded" 889069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // + " the concrete LogFactory class."); 890069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // } 891069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 892069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 893069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 894069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // Return the selected class loader 895069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project return classLoader; 896069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 897069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 898069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 899069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Check cached factories (keyed by contextClassLoader) 900069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 901069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @param contextClassLoader is the context classloader associated 902069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * with the current thread. This allows separate LogFactory objects 903069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * per component within a container, provided each component has 904069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * a distinct context classloader set. This parameter may be null 905069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * in JDK1.1, and in embedded systems where jcl-using code is 906069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * placed in the bootclasspath. 907069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 908069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @return the factory associated with the specified classloader if 909069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * one has previously been created, or null if this is the first time 910069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * we have seen this particular classloader. 911069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 912069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project private static LogFactory getCachedFactory(ClassLoader contextClassLoader) 913069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project { 914069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project LogFactory factory = null; 915069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 916069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (contextClassLoader == null) { 917069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // We have to handle this specially, as factories is a Hashtable 918069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // and those don't accept null as a key value. 919069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // 920069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // nb: nullClassLoaderFactory might be null. That's ok. 921069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project factory = nullClassLoaderFactory; 922069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } else { 923069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project factory = (LogFactory) factories.get(contextClassLoader); 924069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 925069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 926069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project return factory; 927069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 928069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 929069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 930069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Remember this factory, so later calls to LogFactory.getCachedFactory 931069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * can return the previously created object (together with all its 932069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * cached Log objects). 933069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 934069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @param classLoader should be the current context classloader. Note that 935069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * this can be null under some circumstances; this is ok. 936069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 937069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @param factory should be the factory to cache. This should never be null. 938069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 939069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project private static void cacheFactory(ClassLoader classLoader, LogFactory factory) 940069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project { 941069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // Ideally we would assert(factory != null) here. However reporting 942069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // errors from within a logging implementation is a little tricky! 943069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 944069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (factory != null) { 945069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (classLoader == null) { 946069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project nullClassLoaderFactory = factory; 947069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } else { 948069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project factories.put(classLoader, factory); 949069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 950069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 951069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 952069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 953069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 954069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Return a new instance of the specified <code>LogFactory</code> 955069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * implementation class, loaded by the specified class loader. 956069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * If that fails, try the class loader used to load this 957069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * (abstract) LogFactory. 958069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * <p> 959069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * <h2>ClassLoader conflicts</h2> 960069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Note that there can be problems if the specified ClassLoader is not the 961069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * same as the classloader that loaded this class, ie when loading a 962069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * concrete LogFactory subclass via a context classloader. 963069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * <p> 964069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * The problem is the same one that can occur when loading a concrete Log 965069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * subclass via a context classloader. 966069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * <p> 967069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * The problem occurs when code running in the context classloader calls 968069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * class X which was loaded via a parent classloader, and class X then calls 969069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * LogFactory.getFactory (either directly or via LogFactory.getLog). Because 970069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * class X was loaded via the parent, it binds to LogFactory loaded via 971069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * the parent. When the code in this method finds some LogFactoryYYYY 972069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * class in the child (context) classloader, and there also happens to be a 973069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * LogFactory class defined in the child classloader, then LogFactoryYYYY 974069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * will be bound to LogFactory@childloader. It cannot be cast to 975069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * LogFactory@parentloader, ie this method cannot return the object as 976069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * the desired type. Note that it doesn't matter if the LogFactory class 977069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * in the child classloader is identical to the LogFactory class in the 978069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * parent classloader, they are not compatible. 979069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * <p> 980069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * The solution taken here is to simply print out an error message when 981069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * this occurs then throw an exception. The deployer of the application 982069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * must ensure they remove all occurrences of the LogFactory class from 983069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * the child classloader in order to resolve the issue. Note that they 984069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * do not have to move the custom LogFactory subclass; that is ok as 985069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * long as the only LogFactory class it can find to bind to is in the 986069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * parent classloader. 987069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * <p> 988069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @param factoryClass Fully qualified name of the <code>LogFactory</code> 989069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * implementation class 990069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @param classLoader ClassLoader from which to load this class 991069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @param contextClassLoader is the context that this new factory will 992069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * manage logging for. 993069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 994069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @exception LogConfigurationException if a suitable instance 995069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * cannot be created 996069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @since 1.1 997069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 998069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project protected static LogFactory newFactory(final String factoryClass, 999069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project final ClassLoader classLoader, 1000069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project final ClassLoader contextClassLoader) 1001069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project throws LogConfigurationException 1002069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project { 1003069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // Note that any unchecked exceptions thrown by the createFactory 1004069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // method will propagate out of this method; in particular a 1005069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // ClassCastException can be thrown. 1006069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project Object result = AccessController.doPrivileged( 1007069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project new PrivilegedAction() { 1008069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project public Object run() { 1009069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project return createFactory(factoryClass, classLoader); 1010069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 1011069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project }); 1012069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 1013069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (result instanceof LogConfigurationException) { 1014069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project LogConfigurationException ex = (LogConfigurationException) result; 1015069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (isDiagnosticsEnabled()) { 1016069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project logDiagnostic( 1017069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project "An error occurred while loading the factory class:" 1018069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project + ex.getMessage()); 1019069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 1020069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project throw ex; 1021069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 1022069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (isDiagnosticsEnabled()) { 1023069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project logDiagnostic( 1024069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project "Created object " + objectId(result) 1025069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project + " to manage classloader " + objectId(contextClassLoader)); 1026069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 1027069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project return (LogFactory)result; 1028069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 1029069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 1030069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 1031069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Method provided for backwards compatibility; see newFactory version that 1032069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * takes 3 parameters. 1033069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * <p> 1034069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * This method would only ever be called in some rather odd situation. 1035069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Note that this method is static, so overriding in a subclass doesn't 1036069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * have any effect unless this method is called from a method in that 1037069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * subclass. However this method only makes sense to use from the 1038069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * getFactory method, and as that is almost always invoked via 1039069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * LogFactory.getFactory, any custom definition in a subclass would be 1040069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * pointless. Only a class with a custom getFactory method, then invoked 1041069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * directly via CustomFactoryImpl.getFactory or similar would ever call 1042069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * this. Anyway, it's here just in case, though the "managed class loader" 1043069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * value output to the diagnostics will not report the correct value. 1044069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 1045069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project protected static LogFactory newFactory(final String factoryClass, 1046069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project final ClassLoader classLoader) { 1047069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project return newFactory(factoryClass, classLoader, null); 1048069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 1049069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 1050069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 1051069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Implements the operations described in the javadoc for newFactory. 1052069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 1053069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @param factoryClass 1054069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 1055069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @param classLoader used to load the specified factory class. This is 1056069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * expected to be either the TCCL or the classloader which loaded this 1057069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * class. Note that the classloader which loaded this class might be 1058069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * "null" (ie the bootloader) for embedded systems. 1059069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 1060069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @return either a LogFactory object or a LogConfigurationException object. 1061069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @since 1.1 1062069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 1063069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project protected static Object createFactory(String factoryClass, ClassLoader classLoader) { 1064069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 1065069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // This will be used to diagnose bad configurations 1066069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // and allow a useful message to be sent to the user 1067069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project Class logFactoryClass = null; 1068069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project try { 1069069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (classLoader != null) { 1070069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project try { 1071069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // First the given class loader param (thread class loader) 1072069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 1073069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // Warning: must typecast here & allow exception 1074069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // to be generated/caught & recast properly. 1075069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project logFactoryClass = classLoader.loadClass(factoryClass); 1076069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (LogFactory.class.isAssignableFrom(logFactoryClass)) { 1077069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (isDiagnosticsEnabled()) { 1078069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project logDiagnostic( 1079069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project "Loaded class " + logFactoryClass.getName() 1080069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project + " from classloader " + objectId(classLoader)); 1081069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 1082069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } else { 1083069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // 1084069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // This indicates a problem with the ClassLoader tree. 1085069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // An incompatible ClassLoader was used to load the 1086069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // implementation. 1087069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // As the same classes 1088069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // must be available in multiple class loaders, 1089069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // it is very likely that multiple JCL jars are present. 1090069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // The most likely fix for this 1091069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // problem is to remove the extra JCL jars from the 1092069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // ClassLoader hierarchy. 1093069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // 1094069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (isDiagnosticsEnabled()) { 1095069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project logDiagnostic( 1096069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project "Factory class " + logFactoryClass.getName() 1097069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project + " loaded from classloader " + objectId(logFactoryClass.getClassLoader()) 1098069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project + " does not extend '" + LogFactory.class.getName() 1099069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project + "' as loaded by this classloader."); 1100069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project logHierarchy("[BAD CL TREE] ", classLoader); 1101069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 1102069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 1103069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 1104069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project return (LogFactory) logFactoryClass.newInstance(); 1105069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 1106069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } catch (ClassNotFoundException ex) { 1107069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (classLoader == thisClassLoader) { 1108069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // Nothing more to try, onwards. 1109069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (isDiagnosticsEnabled()) { 1110069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project logDiagnostic( 1111069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project "Unable to locate any class called '" + factoryClass 1112069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project + "' via classloader " + objectId(classLoader)); 1113069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 1114069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project throw ex; 1115069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 1116069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // ignore exception, continue 1117069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } catch (NoClassDefFoundError e) { 1118069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (classLoader == thisClassLoader) { 1119069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // Nothing more to try, onwards. 1120069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (isDiagnosticsEnabled()) { 1121069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project logDiagnostic( 1122069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project "Class '" + factoryClass + "' cannot be loaded" 1123069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project + " via classloader " + objectId(classLoader) 1124069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project + " - it depends on some other class that cannot" 1125069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project + " be found."); 1126069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 1127069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project throw e; 1128069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 1129069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // ignore exception, continue 1130069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } catch(ClassCastException e) { 1131069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (classLoader == thisClassLoader) { 1132069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // There's no point in falling through to the code below that 1133069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // tries again with thisClassLoader, because we've just tried 1134069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // loading with that loader (not the TCCL). Just throw an 1135069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // appropriate exception here. 1136069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 1137069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project final boolean implementsLogFactory = implementsLogFactory(logFactoryClass); 1138069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 1139069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // 1140069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // Construct a good message: users may not actual expect that a custom implementation 1141069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // has been specified. Several well known containers use this mechanism to adapt JCL 1142069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // to their native logging system. 1143069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // 1144069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project String msg = 1145069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project "The application has specified that a custom LogFactory implementation should be used but " + 1146069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project "Class '" + factoryClass + "' cannot be converted to '" 1147069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project + LogFactory.class.getName() + "'. "; 1148069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (implementsLogFactory) { 1149069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project msg = msg + "The conflict is caused by the presence of multiple LogFactory classes in incompatible classloaders. " + 1150069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project "Background can be found in http://jakarta.apache.org/commons/logging/tech.html. " + 1151069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project "If you have not explicitly specified a custom LogFactory then it is likely that " + 1152069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project "the container has set one without your knowledge. " + 1153069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project "In this case, consider using the commons-logging-adapters.jar file or " + 1154069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project "specifying the standard LogFactory from the command line. "; 1155069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } else { 1156069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project msg = msg + "Please check the custom implementation. "; 1157069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 1158069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project msg = msg + "Help can be found @http://jakarta.apache.org/commons/logging/troubleshooting.html."; 1159069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 1160069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (isDiagnosticsEnabled()) { 1161069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project logDiagnostic(msg); 1162069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 1163069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 1164069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project ClassCastException ex = new ClassCastException(msg); 1165069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project throw ex; 1166069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 1167069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 1168069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // Ignore exception, continue. Presumably the classloader was the 1169069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // TCCL; the code below will try to load the class via thisClassLoader. 1170069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // This will handle the case where the original calling class is in 1171069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // a shared classpath but the TCCL has a copy of LogFactory and the 1172069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // specified LogFactory implementation; we will fall back to using the 1173069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // LogFactory implementation from the same classloader as this class. 1174069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // 1175069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // Issue: this doesn't handle the reverse case, where this LogFactory 1176069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // is in the webapp, and the specified LogFactory implementation is 1177069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // in a shared classpath. In that case: 1178069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // (a) the class really does implement LogFactory (bad log msg above) 1179069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // (b) the fallback code will result in exactly the same problem. 1180069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 1181069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 1182069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 1183069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /* At this point, either classLoader == null, OR 1184069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * classLoader was unable to load factoryClass. 1185069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 1186069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * In either case, we call Class.forName, which is equivalent 1187069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * to LogFactory.class.getClassLoader().load(name), ie we ignore 1188069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * the classloader parameter the caller passed, and fall back 1189069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * to trying the classloader associated with this class. See the 1190069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * javadoc for the newFactory method for more info on the 1191069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * consequences of this. 1192069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 1193069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Notes: 1194069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * * LogFactory.class.getClassLoader() may return 'null' 1195069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * if LogFactory is loaded by the bootstrap classloader. 1196069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 1197069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // Warning: must typecast here & allow exception 1198069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // to be generated/caught & recast properly. 1199069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (isDiagnosticsEnabled()) { 1200069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project logDiagnostic( 1201069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project "Unable to load factory class via classloader " 1202069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project + objectId(classLoader) 1203069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project + " - trying the classloader associated with this LogFactory."); 1204069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 1205069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project logFactoryClass = Class.forName(factoryClass); 1206069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project return (LogFactory) logFactoryClass.newInstance(); 1207069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } catch (Exception e) { 1208069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // Check to see if we've got a bad configuration 1209069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (isDiagnosticsEnabled()) { 1210069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project logDiagnostic("Unable to create LogFactory instance."); 1211069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 1212069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (logFactoryClass != null 1213069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project && !LogFactory.class.isAssignableFrom(logFactoryClass)) { 1214069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 1215069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project return new LogConfigurationException( 1216069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project "The chosen LogFactory implementation does not extend LogFactory." 1217069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project + " Please check your configuration.", 1218069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project e); 1219069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 1220069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project return new LogConfigurationException(e); 1221069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 1222069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 1223069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 1224069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 1225069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Determines whether the given class actually implements <code>LogFactory</code>. 1226069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Diagnostic information is also logged. 1227069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * <p> 1228069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * <strong>Usage:</strong> to diagnose whether a classloader conflict is the cause 1229069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * of incompatibility. The test used is whether the class is assignable from 1230069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * the <code>LogFactory</code> class loaded by the class's classloader. 1231069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @param logFactoryClass <code>Class</code> which may implement <code>LogFactory</code> 1232069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @return true if the <code>logFactoryClass</code> does extend 1233069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * <code>LogFactory</code> when that class is loaded via the same 1234069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * classloader that loaded the <code>logFactoryClass</code>. 1235069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 1236069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project private static boolean implementsLogFactory(Class logFactoryClass) { 1237069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project boolean implementsLogFactory = false; 1238069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (logFactoryClass != null) { 1239069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project try { 1240069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project ClassLoader logFactoryClassLoader = logFactoryClass.getClassLoader(); 1241069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (logFactoryClassLoader == null) { 1242069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project logDiagnostic("[CUSTOM LOG FACTORY] was loaded by the boot classloader"); 1243069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } else { 1244069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project logHierarchy("[CUSTOM LOG FACTORY] ", logFactoryClassLoader); 1245069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project Class factoryFromCustomLoader 1246069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project = Class.forName("org.apache.commons.logging.LogFactory", false, logFactoryClassLoader); 1247069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project implementsLogFactory = factoryFromCustomLoader.isAssignableFrom(logFactoryClass); 1248069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (implementsLogFactory) { 1249069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project logDiagnostic("[CUSTOM LOG FACTORY] " + logFactoryClass.getName() 1250069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project + " implements LogFactory but was loaded by an incompatible classloader."); 1251069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } else { 1252069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project logDiagnostic("[CUSTOM LOG FACTORY] " + logFactoryClass.getName() 1253069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project + " does not implement LogFactory."); 1254069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 1255069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 1256069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } catch (SecurityException e) { 1257069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // 1258069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // The application is running within a hostile security environment. 1259069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // This will make it very hard to diagnose issues with JCL. 1260069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // Consider running less securely whilst debugging this issue. 1261069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // 1262069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project logDiagnostic("[CUSTOM LOG FACTORY] SecurityException thrown whilst trying to determine whether " + 1263069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project "the compatibility was caused by a classloader conflict: " 1264069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project + e.getMessage()); 1265069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } catch (LinkageError e) { 1266069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // 1267069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // This should be an unusual circumstance. 1268069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // LinkageError's usually indicate that a dependent class has incompatibly changed. 1269069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // Another possibility may be an exception thrown by an initializer. 1270069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // Time for a clean rebuild? 1271069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // 1272069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project logDiagnostic("[CUSTOM LOG FACTORY] LinkageError thrown whilst trying to determine whether " + 1273069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project "the compatibility was caused by a classloader conflict: " 1274069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project + e.getMessage()); 1275069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } catch (ClassNotFoundException e) { 1276069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // 1277069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // LogFactory cannot be loaded by the classloader which loaded the custom factory implementation. 1278069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // The custom implementation is not viable until this is corrected. 1279069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // Ensure that the JCL jar and the custom class are available from the same classloader. 1280069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // Running with diagnostics on should give information about the classloaders used 1281069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // to load the custom factory. 1282069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // 1283069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project logDiagnostic("[CUSTOM LOG FACTORY] LogFactory class cannot be loaded by classloader which loaded the " + 1284069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project "custom LogFactory implementation. Is the custom factory in the right classloader?"); 1285069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 1286069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 1287069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project return implementsLogFactory; 1288069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 1289069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 1290069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 1291069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Applets may run in an environment where accessing resources of a loader is 1292069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * a secure operation, but where the commons-logging library has explicitly 1293069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * been granted permission for that operation. In this case, we need to 1294069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * run the operation using an AccessController. 1295069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 1296069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project private static InputStream getResourceAsStream(final ClassLoader loader, 1297069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project final String name) 1298069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project { 1299069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project return (InputStream)AccessController.doPrivileged( 1300069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project new PrivilegedAction() { 1301069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project public Object run() { 1302069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (loader != null) { 1303069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project return loader.getResourceAsStream(name); 1304069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } else { 1305069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project return ClassLoader.getSystemResourceAsStream(name); 1306069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 1307069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 1308069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project }); 1309069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 1310069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 1311069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 1312069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Given a filename, return an enumeration of URLs pointing to 1313069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * all the occurrences of that filename in the classpath. 1314069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * <p> 1315069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * This is just like ClassLoader.getResources except that the 1316069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * operation is done under an AccessController so that this method will 1317069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * succeed when this jarfile is privileged but the caller is not. 1318069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * This method must therefore remain private to avoid security issues. 1319069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * <p> 1320069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * If no instances are found, an Enumeration is returned whose 1321069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * hasMoreElements method returns false (ie an "empty" enumeration). 1322069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * If resources could not be listed for some reason, null is returned. 1323069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 1324069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project private static Enumeration getResources(final ClassLoader loader, 1325069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project final String name) 1326069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project { 1327069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project PrivilegedAction action = 1328069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project new PrivilegedAction() { 1329069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project public Object run() { 1330069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project try { 1331069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (loader != null) { 1332069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project return loader.getResources(name); 1333069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } else { 1334069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project return ClassLoader.getSystemResources(name); 1335069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 1336069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } catch(IOException e) { 1337069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (isDiagnosticsEnabled()) { 1338069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project logDiagnostic( 1339069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project "Exception while trying to find configuration file " 1340069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project + name + ":" + e.getMessage()); 1341069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 1342069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project return null; 1343069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } catch(NoSuchMethodError e) { 1344069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // we must be running on a 1.1 JVM which doesn't support 1345069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // ClassLoader.getSystemResources; just return null in 1346069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // this case. 1347069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project return null; 1348069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 1349069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 1350069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project }; 1351069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project Object result = AccessController.doPrivileged(action); 1352069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project return (Enumeration) result; 1353069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 1354069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 1355069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 1356069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Given a URL that refers to a .properties file, load that file. 1357069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * This is done under an AccessController so that this method will 1358069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * succeed when this jarfile is privileged but the caller is not. 1359069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * This method must therefore remain private to avoid security issues. 1360069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * <p> 1361069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Null is returned if the URL cannot be opened. 1362069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 1363069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project private static Properties getProperties(final URL url) { 1364069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project PrivilegedAction action = 1365069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project new PrivilegedAction() { 1366069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project public Object run() { 1367069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project try { 1368069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project InputStream stream = url.openStream(); 1369069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (stream != null) { 1370069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project Properties props = new Properties(); 1371069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project props.load(stream); 1372069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project stream.close(); 1373069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project return props; 1374069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 1375069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } catch(IOException e) { 1376069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (isDiagnosticsEnabled()) { 1377069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project logDiagnostic("Unable to read URL " + url); 1378069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 1379069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 1380069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 1381069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project return null; 1382069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 1383069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project }; 1384069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project return (Properties) AccessController.doPrivileged(action); 1385069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 1386069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 1387069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 1388069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Locate a user-provided configuration file. 1389069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * <p> 1390069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * The classpath of the specified classLoader (usually the context classloader) 1391069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * is searched for properties files of the specified name. If none is found, 1392069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * null is returned. If more than one is found, then the file with the greatest 1393069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * value for its PRIORITY property is returned. If multiple files have the 1394069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * same PRIORITY value then the first in the classpath is returned. 1395069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * <p> 1396069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * This differs from the 1.0.x releases; those always use the first one found. 1397069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * However as the priority is a new field, this change is backwards compatible. 1398069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * <p> 1399069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * The purpose of the priority field is to allow a webserver administrator to 1400069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * override logging settings in all webapps by placing a commons-logging.properties 1401069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * file in a shared classpath location with a priority > 0; this overrides any 1402069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * commons-logging.properties files without priorities which are in the 1403069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * webapps. Webapps can also use explicit priorities to override a configuration 1404069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * file in the shared classpath if needed. 1405069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 1406069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project private static final Properties getConfigurationFile( 1407069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project ClassLoader classLoader, String fileName) { 1408069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 1409069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project Properties props = null; 1410069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project double priority = 0.0; 1411069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project URL propsUrl = null; 1412069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project try { 1413069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project Enumeration urls = getResources(classLoader, fileName); 1414069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 1415069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (urls == null) { 1416069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project return null; 1417069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 1418069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 1419069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project while (urls.hasMoreElements()) { 1420069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project URL url = (URL) urls.nextElement(); 1421069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 1422069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project Properties newProps = getProperties(url); 1423069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (newProps != null) { 1424069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (props == null) { 1425069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project propsUrl = url; 1426069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project props = newProps; 1427069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project String priorityStr = props.getProperty(PRIORITY_KEY); 1428069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project priority = 0.0; 1429069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (priorityStr != null) { 1430069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project priority = Double.parseDouble(priorityStr); 1431069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 1432069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 1433069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (isDiagnosticsEnabled()) { 1434069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project logDiagnostic( 1435069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project "[LOOKUP] Properties file found at '" + url + "'" 1436069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project + " with priority " + priority); 1437069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 1438069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } else { 1439069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project String newPriorityStr = newProps.getProperty(PRIORITY_KEY); 1440069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project double newPriority = 0.0; 1441069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (newPriorityStr != null) { 1442069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project newPriority = Double.parseDouble(newPriorityStr); 1443069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 1444069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 1445069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (newPriority > priority) { 1446069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (isDiagnosticsEnabled()) { 1447069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project logDiagnostic( 1448069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project "[LOOKUP] Properties file at '" + url + "'" 1449069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project + " with priority " + newPriority 1450069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project + " overrides file at '" + propsUrl + "'" 1451069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project + " with priority " + priority); 1452069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 1453069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 1454069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project propsUrl = url; 1455069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project props = newProps; 1456069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project priority = newPriority; 1457069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } else { 1458069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (isDiagnosticsEnabled()) { 1459069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project logDiagnostic( 1460069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project "[LOOKUP] Properties file at '" + url + "'" 1461069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project + " with priority " + newPriority 1462069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project + " does not override file at '" + propsUrl + "'" 1463069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project + " with priority " + priority); 1464069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 1465069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 1466069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 1467069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 1468069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 1469069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 1470069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } catch (SecurityException e) { 1471069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (isDiagnosticsEnabled()) { 1472069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project logDiagnostic("SecurityException thrown while trying to find/read config files."); 1473069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 1474069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 1475069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 1476069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (isDiagnosticsEnabled()) { 1477069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (props == null) { 1478069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project logDiagnostic( 1479069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project "[LOOKUP] No properties file of name '" + fileName 1480069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project + "' found."); 1481069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } else { 1482069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project logDiagnostic( 1483069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project "[LOOKUP] Properties file of name '" + fileName 1484069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project + "' found at '" + propsUrl + '"'); 1485069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 1486069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 1487069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 1488069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project return props; 1489069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 1490069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 1491069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 1492069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Determines whether the user wants internal diagnostic output. If so, 1493069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * returns an appropriate writer object. Users can enable diagnostic 1494069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * output by setting the system property named {@link #DIAGNOSTICS_DEST_PROPERTY} to 1495069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * a filename, or the special values STDOUT or STDERR. 1496069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 1497069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project private static void initDiagnostics() { 1498069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project String dest; 1499069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project try { 1500069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project dest = System.getProperty(DIAGNOSTICS_DEST_PROPERTY); 1501069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (dest == null) { 1502069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project return; 1503069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 1504069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } catch(SecurityException ex) { 1505069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // We must be running in some very secure environment. 1506069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // We just have to assume output is not wanted.. 1507069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project return; 1508069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 1509069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 1510069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (dest.equals("STDOUT")) { 1511069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project diagnosticsStream = System.out; 1512069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } else if (dest.equals("STDERR")) { 1513069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project diagnosticsStream = System.err; 1514069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } else { 1515069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project try { 1516069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // open the file in append mode 1517069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project FileOutputStream fos = new FileOutputStream(dest, true); 1518069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project diagnosticsStream = new PrintStream(fos); 1519069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } catch(IOException ex) { 1520069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // We should report this to the user - but how? 1521069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project return; 1522069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 1523069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 1524069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 1525069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // In order to avoid confusion where multiple instances of JCL are 1526069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // being used via different classloaders within the same app, we 1527069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // ensure each logged message has a prefix of form 1528069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // [LogFactory from classloader OID] 1529069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // 1530069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // Note that this prefix should be kept consistent with that 1531069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // in LogFactoryImpl. However here we don't need to output info 1532069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // about the actual *instance* of LogFactory, as all methods that 1533069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // output diagnostics from this class are static. 1534069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project String classLoaderName; 1535069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project try { 1536069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project ClassLoader classLoader = thisClassLoader; 1537069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (thisClassLoader == null) { 1538069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project classLoaderName = "BOOTLOADER"; 1539069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } else { 1540069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project classLoaderName = objectId(classLoader); 1541069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 1542069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } catch(SecurityException e) { 1543069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project classLoaderName = "UNKNOWN"; 1544069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 1545069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project diagnosticPrefix = "[LogFactory from " + classLoaderName + "] "; 1546069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 1547069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 1548069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 1549069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Indicates true if the user has enabled internal logging. 1550069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * <p> 1551069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * By the way, sorry for the incorrect grammar, but calling this method 1552069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * areDiagnosticsEnabled just isn't java beans style. 1553069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 1554069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @return true if calls to logDiagnostic will have any effect. 1555069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @since 1.1 1556069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 1557069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project protected static boolean isDiagnosticsEnabled() { 1558069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project return diagnosticsStream != null; 1559069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 1560069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 1561069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 1562069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Write the specified message to the internal logging destination. 1563069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * <p> 1564069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Note that this method is private; concrete subclasses of this class 1565069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * should not call it because the diagnosticPrefix string this 1566069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * method puts in front of all its messages is LogFactory@...., 1567069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * while subclasses should put SomeSubClass@... 1568069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * <p> 1569069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Subclasses should instead compute their own prefix, then call 1570069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * logRawDiagnostic. Note that calling isDiagnosticsEnabled is 1571069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * fine for subclasses. 1572069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * <p> 1573069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Note that it is safe to call this method before initDiagnostics 1574069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * is called; any output will just be ignored (as isDiagnosticsEnabled 1575069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * will return false). 1576069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 1577069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @param msg is the diagnostic message to be output. 1578069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 1579069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project private static final void logDiagnostic(String msg) { 1580069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (diagnosticsStream != null) { 1581069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project diagnosticsStream.print(diagnosticPrefix); 1582069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project diagnosticsStream.println(msg); 1583069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project diagnosticsStream.flush(); 1584069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 1585069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 1586069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 1587069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 1588069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Write the specified message to the internal logging destination. 1589069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 1590069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @param msg is the diagnostic message to be output. 1591069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @since 1.1 1592069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 1593069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project protected static final void logRawDiagnostic(String msg) { 1594069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (diagnosticsStream != null) { 1595069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project diagnosticsStream.println(msg); 1596069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project diagnosticsStream.flush(); 1597069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 1598069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 1599069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 1600069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 1601069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Generate useful diagnostics regarding the classloader tree for 1602069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * the specified class. 1603069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * <p> 1604069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * As an example, if the specified class was loaded via a webapp's 1605069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * classloader, then you may get the following output: 1606069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * <pre> 1607069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Class com.acme.Foo was loaded via classloader 11111 1608069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * ClassLoader tree: 11111 -> 22222 (SYSTEM) -> 33333 -> BOOT 1609069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * </pre> 1610069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * <p> 1611069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * This method returns immediately if isDiagnosticsEnabled() 1612069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * returns false. 1613069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 1614069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @param clazz is the class whose classloader + tree are to be 1615069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * output. 1616069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 1617069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project private static void logClassLoaderEnvironment(Class clazz) { 1618069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (!isDiagnosticsEnabled()) { 1619069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project return; 1620069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 1621069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 1622069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project try { 1623069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project logDiagnostic("[ENV] Extension directories (java.ext.dir): " + System.getProperty("java.ext.dir")); 1624069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project logDiagnostic("[ENV] Application classpath (java.class.path): " + System.getProperty("java.class.path")); 1625069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } catch(SecurityException ex) { 1626069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project logDiagnostic("[ENV] Security setting prevent interrogation of system classpaths."); 1627069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 1628069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 1629069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project String className = clazz.getName(); 1630069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project ClassLoader classLoader; 1631069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 1632069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project try { 1633069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project classLoader = getClassLoader(clazz); 1634069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } catch(SecurityException ex) { 1635069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // not much useful diagnostics we can print here! 1636069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project logDiagnostic( 1637069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project "[ENV] Security forbids determining the classloader for " + className); 1638069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project return; 1639069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 1640069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 1641069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project logDiagnostic( 1642069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project "[ENV] Class " + className + " was loaded via classloader " 1643069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project + objectId(classLoader)); 1644069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project logHierarchy("[ENV] Ancestry of classloader which loaded " + className + " is ", classLoader); 1645069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 1646069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 1647069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 1648069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Logs diagnostic messages about the given classloader 1649069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * and it's hierarchy. The prefix is prepended to the message 1650069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * and is intended to make it easier to understand the logs. 1651069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @param prefix 1652069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @param classLoader 1653069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 1654069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project private static void logHierarchy(String prefix, ClassLoader classLoader) { 1655069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (!isDiagnosticsEnabled()) { 1656069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project return; 1657069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 1658069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project ClassLoader systemClassLoader; 1659069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (classLoader != null) { 1660069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project final String classLoaderString = classLoader.toString(); 1661069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project logDiagnostic(prefix + objectId(classLoader) + " == '" + classLoaderString + "'"); 1662069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 1663069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 1664069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project try { 1665069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project systemClassLoader = ClassLoader.getSystemClassLoader(); 1666069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } catch(SecurityException ex) { 1667069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project logDiagnostic( 1668069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project prefix + "Security forbids determining the system classloader."); 1669069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project return; 1670069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 1671069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (classLoader != null) { 1672069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project StringBuffer buf = new StringBuffer(prefix + "ClassLoader tree:"); 1673069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project for(;;) { 1674069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project buf.append(objectId(classLoader)); 1675069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (classLoader == systemClassLoader) { 1676069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project buf.append(" (SYSTEM) "); 1677069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 1678069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 1679069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project try { 1680069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project classLoader = classLoader.getParent(); 1681069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } catch(SecurityException ex) { 1682069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project buf.append(" --> SECRET"); 1683069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project break; 1684069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 1685069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 1686069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project buf.append(" --> "); 1687069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (classLoader == null) { 1688069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project buf.append("BOOT"); 1689069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project break; 1690069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 1691069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 1692069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project logDiagnostic(buf.toString()); 1693069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 1694069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 1695069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 1696069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project /** 1697069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * Returns a string that uniquely identifies the specified object, including 1698069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * its class. 1699069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * <p> 1700069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * The returned string is of form "classname@hashcode", ie is the same as 1701069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * the return value of the Object.toString() method, but works even when 1702069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * the specified object's class has overidden the toString method. 1703069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * 1704069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @param o may be null. 1705069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @return a string of form classname@hashcode, or "null" if param o is null. 1706069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project * @since 1.1 1707069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project */ 1708069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project public static String objectId(Object o) { 1709069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (o == null) { 1710069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project return "null"; 1711069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } else { 1712069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project return o.getClass().getName() + "@" + System.identityHashCode(o); 1713069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 1714069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 1715069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 1716069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // ---------------------------------------------------------------------- 1717069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // Static initialiser block to perform initialisation at class load time. 1718069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // 1719069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // We can't do this in the class constructor, as there are many 1720069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // static methods on this class that can be called before any 1721069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // LogFactory instances are created, and they depend upon this 1722069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // stuff having been set up. 1723069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // 1724069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // Note that this block must come after any variable declarations used 1725069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // by any methods called from this block, as we want any static initialiser 1726069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // associated with the variable to run first. If static initialisers for 1727069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // variables run after this code, then (a) their value might be needed 1728069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // by methods called from here, and (b) they might *override* any value 1729069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // computed here! 1730069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // 1731069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // So the wisest thing to do is just to place this code at the very end 1732069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // of the class file. 1733069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // ---------------------------------------------------------------------- 1734069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project 1735069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project static { 1736069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project // note: it's safe to call methods before initDiagnostics. 1737069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project thisClassLoader = getClassLoader(LogFactory.class); 1738069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project initDiagnostics(); 1739069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project logClassLoaderEnvironment(LogFactory.class); 1740069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project factories = createFactoryStore(); 1741069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project if (isDiagnosticsEnabled()) { 1742069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project logDiagnostic("BOOTSTRAP COMPLETED"); 1743069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 1744069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project } 1745069490a5ca2fd1988d29daf45d892f47ad665115The Android Open Source Project} 1746