You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@commons.apache.org by gg...@apache.org on 2024/07/04 12:10:53 UTC
svn commit: r1086913 [18/46] - in /websites/production/commons/content/proper/commons-logging: ./ apidocs/ apidocs/legal/ apidocs/org/apache/commons/logging/ apidocs/org/apache/commons/logging/class-use/ apidocs/org/apache/commons/logging/impl/ apidocs...
Modified: websites/production/commons/content/proper/commons-logging/apidocs/src-html/org/apache/commons/logging/LogFactory.html
==============================================================================
--- websites/production/commons/content/proper/commons-logging/apidocs/src-html/org/apache/commons/logging/LogFactory.html (original)
+++ websites/production/commons/content/proper/commons-logging/apidocs/src-html/org/apache/commons/logging/LogFactory.html Thu Jul 4 12:10:51 2024
@@ -1,7 +1,7 @@
<!DOCTYPE HTML>
<html lang="en">
<head>
-<!-- Generated by javadoc (21) -->
+<!-- Generated by javadoc (17) -->
<title>Source code</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="source: package: org.apache.commons.logging, class: LogFactory">
@@ -56,1580 +56,1601 @@
<span class="source-line-no">043</span><span id="line-43"> * <strong>IMPLEMENTATION NOTE</strong> - This implementation is heavily</span>
<span class="source-line-no">044</span><span id="line-44"> * based on the SAXParserFactory and DocumentBuilderFactory implementations</span>
<span class="source-line-no">045</span><span id="line-45"> * (corresponding to the JAXP pluggability APIs) found in Apache Xerces.</span>
-<span class="source-line-no">046</span><span id="line-46"> */</span>
-<span class="source-line-no">047</span><span id="line-47">public abstract class LogFactory {</span>
-<span class="source-line-no">048</span><span id="line-48"> // Implementation note re AccessController usage</span>
-<span class="source-line-no">049</span><span id="line-49"> //</span>
-<span class="source-line-no">050</span><span id="line-50"> // It is important to keep code invoked via an AccessController to small</span>
-<span class="source-line-no">051</span><span id="line-51"> // auditable blocks. Such code must carefully evaluate all user input</span>
-<span class="source-line-no">052</span><span id="line-52"> // (parameters, system properties, configuration file contents, etc). As an</span>
-<span class="source-line-no">053</span><span id="line-53"> // example, a Log implementation should not write to its log file</span>
-<span class="source-line-no">054</span><span id="line-54"> // with an AccessController anywhere in the call stack, otherwise an</span>
-<span class="source-line-no">055</span><span id="line-55"> // insecure application could configure the log implementation to write</span>
-<span class="source-line-no">056</span><span id="line-56"> // to a protected file using the privileges granted to JCL rather than</span>
-<span class="source-line-no">057</span><span id="line-57"> // to the calling application.</span>
-<span class="source-line-no">058</span><span id="line-58"> //</span>
-<span class="source-line-no">059</span><span id="line-59"> // Under no circumstance should a non-private method return data that is</span>
-<span class="source-line-no">060</span><span id="line-60"> // retrieved via an AccessController. That would allow an insecure application</span>
-<span class="source-line-no">061</span><span id="line-61"> // to invoke that method and obtain data that it is not permitted to have.</span>
-<span class="source-line-no">062</span><span id="line-62"> //</span>
-<span class="source-line-no">063</span><span id="line-63"> // Invoking user-supplied code with an AccessController set is not a major</span>
-<span class="source-line-no">064</span><span id="line-64"> // issue (for example, invoking the constructor of the class specified by</span>
-<span class="source-line-no">065</span><span id="line-65"> // HASHTABLE_IMPLEMENTATION_PROPERTY). That class will be in a different</span>
-<span class="source-line-no">066</span><span id="line-66"> // trust domain, and therefore must have permissions to do whatever it</span>
-<span class="source-line-no">067</span><span id="line-67"> // is trying to do regardless of the permissions granted to JCL. There is</span>
-<span class="source-line-no">068</span><span id="line-68"> // a slight issue in that untrusted code may point that environment variable</span>
-<span class="source-line-no">069</span><span id="line-69"> // to another trusted library, in which case the code runs if both that</span>
-<span class="source-line-no">070</span><span id="line-70"> // library and JCL have the necessary permissions even when the untrusted</span>
-<span class="source-line-no">071</span><span id="line-71"> // caller does not. That's a pretty hard route to exploit though.</span>
-<span class="source-line-no">072</span><span id="line-72"></span>
-<span class="source-line-no">073</span><span id="line-73"> /**</span>
-<span class="source-line-no">074</span><span id="line-74"> * The name ({@code priority}) of the key in the configuration file used to</span>
-<span class="source-line-no">075</span><span id="line-75"> * specify the priority of that particular configuration file. The associated value</span>
-<span class="source-line-no">076</span><span id="line-76"> * is a floating-point number; higher values take priority over lower values.</span>
-<span class="source-line-no">077</span><span id="line-77"> */</span>
-<span class="source-line-no">078</span><span id="line-78"> public static final String PRIORITY_KEY = "priority";</span>
-<span class="source-line-no">079</span><span id="line-79"></span>
-<span class="source-line-no">080</span><span id="line-80"> /**</span>
-<span class="source-line-no">081</span><span id="line-81"> * The name ({@code use_tccl}) of the key in the configuration file used</span>
-<span class="source-line-no">082</span><span id="line-82"> * to specify whether logging classes should be loaded via the thread</span>
-<span class="source-line-no">083</span><span id="line-83"> * context class loader (TCCL), or not. By default, the TCCL is used.</span>
-<span class="source-line-no">084</span><span id="line-84"> */</span>
-<span class="source-line-no">085</span><span id="line-85"> public static final String TCCL_KEY = "use_tccl";</span>
-<span class="source-line-no">086</span><span id="line-86"></span>
-<span class="source-line-no">087</span><span id="line-87"> /**</span>
-<span class="source-line-no">088</span><span id="line-88"> * The name ({@code org.apache.commons.logging.LogFactory}) of the property</span>
-<span class="source-line-no">089</span><span id="line-89"> * used to identify the LogFactory implementation</span>
-<span class="source-line-no">090</span><span id="line-90"> * class name. This can be used as a system property, or as an entry in a</span>
-<span class="source-line-no">091</span><span id="line-91"> * configuration properties file.</span>
-<span class="source-line-no">092</span><span id="line-92"> */</span>
-<span class="source-line-no">093</span><span id="line-93"> public static final String FACTORY_PROPERTY = "org.apache.commons.logging.LogFactory";</span>
-<span class="source-line-no">094</span><span id="line-94"></span>
-<span class="source-line-no">095</span><span id="line-95"> private static final String FACTORY_LOG4J_API = "org.apache.commons.logging.impl.Log4jApiLogFactory";</span>
-<span class="source-line-no">096</span><span id="line-96"> private static final String LOG4J_API_LOGGER = "org.apache.logging.log4j.Logger";</span>
-<span class="source-line-no">097</span><span id="line-97"> private static final String LOG4J_TO_SLF4J_BRIDGE = "org.apache.logging.slf4j.SLF4JProvider";</span>
-<span class="source-line-no">098</span><span id="line-98"></span>
-<span class="source-line-no">099</span><span id="line-99"> private static final String FACTORY_SLF4J = "org.apache.commons.logging.impl.Slf4jLogFactory";</span>
-<span class="source-line-no">100</span><span id="line-100"> private static final String SLF4J_API_LOGGER = "org.slf4j.Logger";</span>
-<span class="source-line-no">101</span><span id="line-101"></span>
-<span class="source-line-no">102</span><span id="line-102"> /**</span>
-<span class="source-line-no">103</span><span id="line-103"> * The fully qualified class name of the fallback {@code LogFactory}</span>
-<span class="source-line-no">104</span><span id="line-104"> * implementation class to use, if no other can be found.</span>
-<span class="source-line-no">105</span><span id="line-105"> */</span>
-<span class="source-line-no">106</span><span id="line-106"> public static final String FACTORY_DEFAULT = "org.apache.commons.logging.impl.LogFactoryImpl";</span>
-<span class="source-line-no">107</span><span id="line-107"></span>
-<span class="source-line-no">108</span><span id="line-108"> /**</span>
-<span class="source-line-no">109</span><span id="line-109"> * The name ({@code commons-logging.properties}) of the properties file to search for.</span>
-<span class="source-line-no">110</span><span id="line-110"> */</span>
-<span class="source-line-no">111</span><span id="line-111"> public static final String FACTORY_PROPERTIES = "commons-logging.properties";</span>
-<span class="source-line-no">112</span><span id="line-112"></span>
-<span class="source-line-no">113</span><span id="line-113"> /**</span>
-<span class="source-line-no">114</span><span id="line-114"> * JDK 1.3+ <a href="https://java.sun.com/j2se/1.3/docs/guide/jar/jar.html#Service%20Provider"></span>
-<span class="source-line-no">115</span><span id="line-115"> * 'Service Provider' specification</a>.</span>
-<span class="source-line-no">116</span><span id="line-116"> */</span>
-<span class="source-line-no">117</span><span id="line-117"> protected static final String SERVICE_ID =</span>
-<span class="source-line-no">118</span><span id="line-118"> "META-INF/services/org.apache.commons.logging.LogFactory";</span>
-<span class="source-line-no">119</span><span id="line-119"></span>
-<span class="source-line-no">120</span><span id="line-120"> /**</span>
-<span class="source-line-no">121</span><span id="line-121"> * The name ({@code org.apache.commons.logging.diagnostics.dest})</span>
-<span class="source-line-no">122</span><span id="line-122"> * of the property used to enable internal commons-logging</span>
-<span class="source-line-no">123</span><span id="line-123"> * diagnostic output, in order to get information on what logging</span>
-<span class="source-line-no">124</span><span id="line-124"> * implementations are being discovered, what class loaders they</span>
-<span class="source-line-no">125</span><span id="line-125"> * are loaded through, etc.</span>
-<span class="source-line-no">126</span><span id="line-126"> * <p></span>
-<span class="source-line-no">127</span><span id="line-127"> * If a system property of this name is set then the value is</span>
-<span class="source-line-no">128</span><span id="line-128"> * assumed to be the name of a file. The special strings</span>
-<span class="source-line-no">129</span><span id="line-129"> * STDOUT or STDERR (case-sensitive) indicate output to</span>
-<span class="source-line-no">130</span><span id="line-130"> * System.out and System.err respectively.</span>
-<span class="source-line-no">131</span><span id="line-131"> * <p></span>
-<span class="source-line-no">132</span><span id="line-132"> * Diagnostic logging should be used only to debug problematic</span>
-<span class="source-line-no">133</span><span id="line-133"> * configurations and should not be set in normal production use.</span>
-<span class="source-line-no">134</span><span id="line-134"> */</span>
-<span class="source-line-no">135</span><span id="line-135"> public static final String DIAGNOSTICS_DEST_PROPERTY =</span>
-<span class="source-line-no">136</span><span id="line-136"> "org.apache.commons.logging.diagnostics.dest";</span>
-<span class="source-line-no">137</span><span id="line-137"></span>
-<span class="source-line-no">138</span><span id="line-138"> /**</span>
-<span class="source-line-no">139</span><span id="line-139"> * When null (the usual case), no diagnostic output will be</span>
-<span class="source-line-no">140</span><span id="line-140"> * generated by LogFactory or LogFactoryImpl. When non-null,</span>
-<span class="source-line-no">141</span><span id="line-141"> * interesting events will be written to the specified object.</span>
-<span class="source-line-no">142</span><span id="line-142"> */</span>
-<span class="source-line-no">143</span><span id="line-143"> private static final PrintStream DIAGNOSTICS_STREAM;</span>
-<span class="source-line-no">144</span><span id="line-144"></span>
-<span class="source-line-no">145</span><span id="line-145"> /**</span>
-<span class="source-line-no">146</span><span id="line-146"> * A string that gets prefixed to every message output by the</span>
-<span class="source-line-no">147</span><span id="line-147"> * logDiagnostic method, so that users can clearly see which</span>
-<span class="source-line-no">148</span><span id="line-148"> * LogFactory class is generating the output.</span>
-<span class="source-line-no">149</span><span id="line-149"> */</span>
-<span class="source-line-no">150</span><span id="line-150"> private static final String diagnosticPrefix;</span>
-<span class="source-line-no">151</span><span id="line-151"></span>
-<span class="source-line-no">152</span><span id="line-152"> /**</span>
-<span class="source-line-no">153</span><span id="line-153"> * Setting this system property</span>
-<span class="source-line-no">154</span><span id="line-154"> * ({@code org.apache.commons.logging.LogFactory.HashtableImpl})</span>
-<span class="source-line-no">155</span><span id="line-155"> * value allows the {@code Hashtable} used to store</span>
-<span class="source-line-no">156</span><span id="line-156"> * class loaders to be substituted by an alternative implementation.</span>
-<span class="source-line-no">157</span><span id="line-157"> * <p></span>
-<span class="source-line-no">158</span><span id="line-158"> * <strong>Note:</strong> {@code LogFactory} will print:</span>
-<span class="source-line-no">159</span><span id="line-159"> * <pre></span>
-<span class="source-line-no">160</span><span id="line-160"> * [ERROR] LogFactory: Load of custom hashtable failed</span>
-<span class="source-line-no">161</span><span id="line-161"> * </pre></span>
-<span class="source-line-no">162</span><span id="line-162"> * to system error and then continue using a standard Hashtable.</span>
-<span class="source-line-no">163</span><span id="line-163"> * <p></span>
-<span class="source-line-no">164</span><span id="line-164"> * <strong>Usage:</strong> Set this property when Java is invoked</span>
-<span class="source-line-no">165</span><span id="line-165"> * and {@code LogFactory} will attempt to load a new instance</span>
-<span class="source-line-no">166</span><span id="line-166"> * of the given implementation class.</span>
-<span class="source-line-no">167</span><span id="line-167"> * For example, running the following ant scriplet:</span>
-<span class="source-line-no">168</span><span id="line-168"> * <pre></span>
-<span class="source-line-no">169</span><span id="line-169"> * &lt;java classname="${test.runner}" fork="yes" failonerror="${test.failonerror}"&gt;</span>
-<span class="source-line-no">170</span><span id="line-170"> * ...</span>
-<span class="source-line-no">171</span><span id="line-171"> * &lt;sysproperty</span>
-<span class="source-line-no">172</span><span id="line-172"> * key="org.apache.commons.logging.LogFactory.HashtableImpl"</span>
-<span class="source-line-no">173</span><span id="line-173"> * value="org.apache.commons.logging.AltHashtable"/&gt;</span>
-<span class="source-line-no">174</span><span id="line-174"> * &lt;/java&gt;</span>
-<span class="source-line-no">175</span><span id="line-175"> * </pre></span>
-<span class="source-line-no">176</span><span id="line-176"> * will mean that {@code LogFactory} will load an instance of</span>
-<span class="source-line-no">177</span><span id="line-177"> * {@code org.apache.commons.logging.AltHashtable}.</span>
-<span class="source-line-no">178</span><span id="line-178"> * <p></span>
-<span class="source-line-no">179</span><span id="line-179"> * A typical use case is to allow a custom</span>
-<span class="source-line-no">180</span><span id="line-180"> * Hashtable implementation using weak references to be substituted.</span>
-<span class="source-line-no">181</span><span id="line-181"> * This will allow class loaders to be garbage collected without</span>
-<span class="source-line-no">182</span><span id="line-182"> * the need to release them (on 1.3+ JVMs only, of course ;).</span>
-<span class="source-line-no">183</span><span id="line-183"> */</span>
-<span class="source-line-no">184</span><span id="line-184"> public static final String HASHTABLE_IMPLEMENTATION_PROPERTY =</span>
-<span class="source-line-no">185</span><span id="line-185"> "org.apache.commons.logging.LogFactory.HashtableImpl";</span>
-<span class="source-line-no">186</span><span id="line-186"></span>
-<span class="source-line-no">187</span><span id="line-187"> /** Name used to load the weak hashtable implementation by names. */</span>
-<span class="source-line-no">188</span><span id="line-188"> private static final String WEAK_HASHTABLE_CLASSNAME =</span>
-<span class="source-line-no">189</span><span id="line-189"> "org.apache.commons.logging.impl.WeakHashtable";</span>
-<span class="source-line-no">190</span><span id="line-190"></span>
-<span class="source-line-no">191</span><span id="line-191"> /**</span>
-<span class="source-line-no">192</span><span id="line-192"> * A reference to the class loader that loaded this class. This is the</span>
-<span class="source-line-no">193</span><span id="line-193"> * same as LogFactory.class.getClassLoader(). However computing this</span>
-<span class="source-line-no">194</span><span id="line-194"> * value isn't quite as simple as that, as we potentially need to use</span>
-<span class="source-line-no">195</span><span id="line-195"> * AccessControllers etc. It's more efficient to compute it once and</span>
-<span class="source-line-no">196</span><span id="line-196"> * cache it here.</span>
-<span class="source-line-no">197</span><span id="line-197"> */</span>
-<span class="source-line-no">198</span><span id="line-198"> private static final WeakReference<ClassLoader> thisClassLoaderRef;</span>
-<span class="source-line-no">199</span><span id="line-199"></span>
-<span class="source-line-no">200</span><span id="line-200"> /**</span>
-<span class="source-line-no">201</span><span id="line-201"> * Maximum number of {@link ServiceLoader} errors to ignore, while</span>
-<span class="source-line-no">202</span><span id="line-202"> * looking for an implementation.</span>
-<span class="source-line-no">203</span><span id="line-203"> */</span>
-<span class="source-line-no">204</span><span id="line-204"> private static final int MAX_BROKEN_SERVICES = 3;</span>
-<span class="source-line-no">205</span><span id="line-205"></span>
-<span class="source-line-no">206</span><span id="line-206"> /**</span>
-<span class="source-line-no">207</span><span id="line-207"> * The previously constructed {@code LogFactory} instances, keyed by</span>
-<span class="source-line-no">208</span><span id="line-208"> * the {@code ClassLoader} with which it was created.</span>
-<span class="source-line-no">209</span><span id="line-209"> */</span>
-<span class="source-line-no">210</span><span id="line-210"> protected static Hashtable<ClassLoader, LogFactory> factories;</span>
-<span class="source-line-no">211</span><span id="line-211"></span>
-<span class="source-line-no">212</span><span id="line-212"> /**</span>
-<span class="source-line-no">213</span><span id="line-213"> * Previously constructed {@code LogFactory} instance as in the</span>
-<span class="source-line-no">214</span><span id="line-214"> * {@code factories} map, but for the case where</span>
-<span class="source-line-no">215</span><span id="line-215"> * {@code getClassLoader} returns {@code null}.</span>
-<span class="source-line-no">216</span><span id="line-216"> * This can happen when:</span>
-<span class="source-line-no">217</span><span id="line-217"> * <ul></span>
-<span class="source-line-no">218</span><span id="line-218"> * <li>using JDK1.1 and the calling code is loaded via the system</span>
-<span class="source-line-no">219</span><span id="line-219"> * class loader (very common)</li></span>
-<span class="source-line-no">220</span><span id="line-220"> * <li>using JDK1.2+ and the calling code is loaded via the boot</span>
-<span class="source-line-no">221</span><span id="line-221"> * class loader (only likely for embedded systems work).</li></span>
-<span class="source-line-no">222</span><span id="line-222"> * </ul></span>
-<span class="source-line-no">223</span><span id="line-223"> * Note that {@code factories} is a <i>Hashtable</i> (not a HashMap),</span>
-<span class="source-line-no">224</span><span id="line-224"> * and hashtables don't allow null as a key.</span>
-<span class="source-line-no">225</span><span id="line-225"> * @deprecated since 1.1.2</span>
-<span class="source-line-no">226</span><span id="line-226"> */</span>
-<span class="source-line-no">227</span><span id="line-227"> @Deprecated</span>
-<span class="source-line-no">228</span><span id="line-228"> protected static volatile LogFactory nullClassLoaderFactory;</span>
-<span class="source-line-no">229</span><span id="line-229"></span>
-<span class="source-line-no">230</span><span id="line-230"> static {</span>
-<span class="source-line-no">231</span><span id="line-231"> // note: it's safe to call methods before initDiagnostics (though</span>
-<span class="source-line-no">232</span><span id="line-232"> // diagnostic output gets discarded).</span>
-<span class="source-line-no">233</span><span id="line-233"> final ClassLoader thisClassLoader = getClassLoader(LogFactory.class);</span>
-<span class="source-line-no">234</span><span id="line-234"> thisClassLoaderRef = new WeakReference<>(thisClassLoader);</span>
-<span class="source-line-no">235</span><span id="line-235"> // In order to avoid confusion where multiple instances of JCL are</span>
-<span class="source-line-no">236</span><span id="line-236"> // being used via different class loaders within the same app, we</span>
-<span class="source-line-no">237</span><span id="line-237"> // ensure each logged message has a prefix of form</span>
-<span class="source-line-no">238</span><span id="line-238"> // [LogFactory from class loader OID]</span>
-<span class="source-line-no">239</span><span id="line-239"> //</span>
-<span class="source-line-no">240</span><span id="line-240"> // Note that this prefix should be kept consistent with that</span>
-<span class="source-line-no">241</span><span id="line-241"> // in LogFactoryImpl. However here we don't need to output info</span>
-<span class="source-line-no">242</span><span id="line-242"> // about the actual *instance* of LogFactory, as all methods that</span>
-<span class="source-line-no">243</span><span id="line-243"> // output diagnostics from this class are static.</span>
-<span class="source-line-no">244</span><span id="line-244"> String classLoaderName;</span>
-<span class="source-line-no">245</span><span id="line-245"> try {</span>
-<span class="source-line-no">246</span><span id="line-246"> if (thisClassLoader == null) {</span>
-<span class="source-line-no">247</span><span id="line-247"> classLoaderName = "BOOTLOADER";</span>
-<span class="source-line-no">248</span><span id="line-248"> } else {</span>
-<span class="source-line-no">249</span><span id="line-249"> classLoaderName = objectId(thisClassLoader);</span>
-<span class="source-line-no">250</span><span id="line-250"> }</span>
-<span class="source-line-no">251</span><span id="line-251"> } catch (final SecurityException e) {</span>
-<span class="source-line-no">252</span><span id="line-252"> classLoaderName = "UNKNOWN";</span>
-<span class="source-line-no">253</span><span id="line-253"> }</span>
-<span class="source-line-no">254</span><span id="line-254"> diagnosticPrefix = "[LogFactory from " + classLoaderName + "] ";</span>
-<span class="source-line-no">255</span><span id="line-255"> DIAGNOSTICS_STREAM = initDiagnostics();</span>
-<span class="source-line-no">256</span><span id="line-256"> logClassLoaderEnvironment(LogFactory.class);</span>
-<span class="source-line-no">257</span><span id="line-257"> factories = createFactoryStore();</span>
-<span class="source-line-no">258</span><span id="line-258"> if (isDiagnosticsEnabled()) {</span>
-<span class="source-line-no">259</span><span id="line-259"> logDiagnostic("BOOTSTRAP COMPLETED");</span>
-<span class="source-line-no">260</span><span id="line-260"> }</span>
-<span class="source-line-no">261</span><span id="line-261"> }</span>
-<span class="source-line-no">262</span><span id="line-262"></span>
-<span class="source-line-no">263</span><span id="line-263"> /**</span>
-<span class="source-line-no">264</span><span id="line-264"> * Remember this factory, so later calls to LogFactory.getCachedFactory</span>
-<span class="source-line-no">265</span><span id="line-265"> * can return the previously created object (together with all its</span>
-<span class="source-line-no">266</span><span id="line-266"> * cached Log objects).</span>
-<span class="source-line-no">267</span><span id="line-267"> *</span>
-<span class="source-line-no">268</span><span id="line-268"> * @param classLoader should be the current context class loader. Note that</span>
-<span class="source-line-no">269</span><span id="line-269"> * this can be null under some circumstances; this is ok.</span>
-<span class="source-line-no">270</span><span id="line-270"> * @param factory should be the factory to cache. This should never be null.</span>
-<span class="source-line-no">271</span><span id="line-271"> */</span>
-<span class="source-line-no">272</span><span id="line-272"> private static void cacheFactory(final ClassLoader classLoader, final LogFactory factory) {</span>
-<span class="source-line-no">273</span><span id="line-273"> // Ideally we would assert(factory != null) here. However reporting</span>
-<span class="source-line-no">274</span><span id="line-274"> // errors from within a logging implementation is a little tricky!</span>
-<span class="source-line-no">275</span><span id="line-275"></span>
-<span class="source-line-no">276</span><span id="line-276"> if (factory != null) {</span>
-<span class="source-line-no">277</span><span id="line-277"> if (classLoader == null) {</span>
-<span class="source-line-no">278</span><span id="line-278"> nullClassLoaderFactory = factory;</span>
-<span class="source-line-no">279</span><span id="line-279"> } else {</span>
-<span class="source-line-no">280</span><span id="line-280"> factories.put(classLoader, factory);</span>
-<span class="source-line-no">281</span><span id="line-281"> }</span>
-<span class="source-line-no">282</span><span id="line-282"> }</span>
-<span class="source-line-no">283</span><span id="line-283"> }</span>
-<span class="source-line-no">284</span><span id="line-284"></span>
-<span class="source-line-no">285</span><span id="line-285"> /**</span>
-<span class="source-line-no">286</span><span id="line-286"> * Implements the operations described in the Javadoc for newFactory.</span>
-<span class="source-line-no">287</span><span id="line-287"> *</span>
-<span class="source-line-no">288</span><span id="line-288"> * @param factoryClassName Factory class.</span>
-<span class="source-line-no">289</span><span id="line-289"> * @param classLoader used to load the specified factory class. This is expected to be either the TCCL or the class loader which loaded this class.</span>
-<span class="source-line-no">290</span><span id="line-290"> * Note that the class loader which loaded this class might be "null" (for example, the boot loader) for embedded systems.</span>
-<span class="source-line-no">291</span><span id="line-291"> * @return either a LogFactory object or a LogConfigurationException object.</span>
-<span class="source-line-no">292</span><span id="line-292"> * @since 1.1</span>
-<span class="source-line-no">293</span><span id="line-293"> */</span>
-<span class="source-line-no">294</span><span id="line-294"> protected static Object createFactory(final String factoryClassName, final ClassLoader classLoader) {</span>
-<span class="source-line-no">295</span><span id="line-295"> // This will be used to diagnose bad configurations</span>
-<span class="source-line-no">296</span><span id="line-296"> // and allow a useful message to be sent to the user</span>
-<span class="source-line-no">297</span><span id="line-297"> Class<?> logFactoryClass = null;</span>
-<span class="source-line-no">298</span><span id="line-298"> try {</span>
-<span class="source-line-no">299</span><span id="line-299"> if (classLoader != null) {</span>
-<span class="source-line-no">300</span><span id="line-300"> try {</span>
-<span class="source-line-no">301</span><span id="line-301"> // First the given class loader param (thread class loader)</span>
-<span class="source-line-no">302</span><span id="line-302"></span>
-<span class="source-line-no">303</span><span id="line-303"> // Warning: must typecast here & allow exception</span>
-<span class="source-line-no">304</span><span id="line-304"> // to be generated/caught & recast properly.</span>
-<span class="source-line-no">305</span><span id="line-305"> logFactoryClass = classLoader.loadClass(factoryClassName);</span>
-<span class="source-line-no">306</span><span id="line-306"> if (LogFactory.class.isAssignableFrom(logFactoryClass)) {</span>
-<span class="source-line-no">307</span><span id="line-307"> if (isDiagnosticsEnabled()) {</span>
-<span class="source-line-no">308</span><span id="line-308"> logDiagnostic("Loaded class " + logFactoryClass.getName() + " from class loader " + objectId(classLoader));</span>
-<span class="source-line-no">309</span><span id="line-309"> }</span>
-<span class="source-line-no">310</span><span id="line-310"> } else //</span>
-<span class="source-line-no">311</span><span id="line-311"> // This indicates a problem with the ClassLoader tree.</span>
-<span class="source-line-no">312</span><span id="line-312"> // An incompatible ClassLoader was used to load the</span>
-<span class="source-line-no">313</span><span id="line-313"> // implementation.</span>
-<span class="source-line-no">314</span><span id="line-314"> // As the same classes</span>
-<span class="source-line-no">315</span><span id="line-315"> // must be available in multiple class loaders,</span>
-<span class="source-line-no">316</span><span id="line-316"> // it is very likely that multiple JCL jars are present.</span>
-<span class="source-line-no">317</span><span id="line-317"> // The most likely fix for this</span>
-<span class="source-line-no">318</span><span id="line-318"> // problem is to remove the extra JCL jars from the</span>
-<span class="source-line-no">319</span><span id="line-319"> // ClassLoader hierarchy.</span>
-<span class="source-line-no">320</span><span id="line-320"> //</span>
-<span class="source-line-no">321</span><span id="line-321"> if (isDiagnosticsEnabled()) {</span>
-<span class="source-line-no">322</span><span id="line-322"> logDiagnostic("Factory class " + logFactoryClass.getName() + " loaded from class loader " + objectId(logFactoryClass.getClassLoader())</span>
-<span class="source-line-no">323</span><span id="line-323"> + " does not extend '" + LogFactory.class.getName() + "' as loaded by this class loader.");</span>
-<span class="source-line-no">324</span><span id="line-324"> logHierarchy("[BAD CL TREE] ", classLoader);</span>
-<span class="source-line-no">325</span><span id="line-325"> }</span>
-<span class="source-line-no">326</span><span id="line-326"></span>
-<span class="source-line-no">327</span><span id="line-327"> return logFactoryClass.getConstructor().newInstance();</span>
-<span class="source-line-no">328</span><span id="line-328"></span>
-<span class="source-line-no">329</span><span id="line-329"> } catch (final ClassNotFoundException ex) {</span>
-<span class="source-line-no">330</span><span id="line-330"> if (classLoader == thisClassLoaderRef.get()) {</span>
-<span class="source-line-no">331</span><span id="line-331"> // Nothing more to try, onwards.</span>
-<span class="source-line-no">332</span><span id="line-332"> if (isDiagnosticsEnabled()) {</span>
-<span class="source-line-no">333</span><span id="line-333"> logDiagnostic("Unable to locate any class called '" + factoryClassName + "' via class loader " + objectId(classLoader));</span>
-<span class="source-line-no">334</span><span id="line-334"> }</span>
-<span class="source-line-no">335</span><span id="line-335"> throw ex;</span>
-<span class="source-line-no">336</span><span id="line-336"> }</span>
-<span class="source-line-no">337</span><span id="line-337"> // ignore exception, continue</span>
-<span class="source-line-no">338</span><span id="line-338"> } catch (final NoClassDefFoundError e) {</span>
-<span class="source-line-no">339</span><span id="line-339"> if (classLoader == thisClassLoaderRef.get()) {</span>
-<span class="source-line-no">340</span><span id="line-340"> // Nothing more to try, onwards.</span>
-<span class="source-line-no">341</span><span id="line-341"> if (isDiagnosticsEnabled()) {</span>
-<span class="source-line-no">342</span><span id="line-342"> logDiagnostic("Class '" + factoryClassName + "' cannot be loaded" + " via class loader " + objectId(classLoader)</span>
-<span class="source-line-no">343</span><span id="line-343"> + " - it depends on some other class that cannot be found.");</span>
-<span class="source-line-no">344</span><span id="line-344"> }</span>
-<span class="source-line-no">345</span><span id="line-345"> throw e;</span>
-<span class="source-line-no">346</span><span id="line-346"> }</span>
-<span class="source-line-no">347</span><span id="line-347"> // ignore exception, continue</span>
-<span class="source-line-no">348</span><span id="line-348"> } catch (final ClassCastException e) {</span>
-<span class="source-line-no">349</span><span id="line-349"> if (classLoader == thisClassLoaderRef.get()) {</span>
-<span class="source-line-no">350</span><span id="line-350"> // There's no point in falling through to the code below that</span>
-<span class="source-line-no">351</span><span id="line-351"> // tries again with thisClassLoaderRef, because we've just tried</span>
-<span class="source-line-no">352</span><span id="line-352"> // loading with that loader (not the TCCL). Just throw an</span>
-<span class="source-line-no">353</span><span id="line-353"> // appropriate exception here.</span>
-<span class="source-line-no">354</span><span id="line-354"></span>
-<span class="source-line-no">355</span><span id="line-355"> final boolean implementsLogFactory = implementsLogFactory(logFactoryClass);</span>
-<span class="source-line-no">356</span><span id="line-356"></span>
-<span class="source-line-no">357</span><span id="line-357"> //</span>
-<span class="source-line-no">358</span><span id="line-358"> // Construct a good message: users may not actual expect that a custom implementation</span>
-<span class="source-line-no">359</span><span id="line-359"> // has been specified. Several well known containers use this mechanism to adapt JCL</span>
-<span class="source-line-no">360</span><span id="line-360"> // to their native logging system.</span>
-<span class="source-line-no">361</span><span id="line-361"> //</span>
-<span class="source-line-no">362</span><span id="line-362"> final StringBuilder msg = new StringBuilder();</span>
-<span class="source-line-no">363</span><span id="line-363"> msg.append("The application has specified that a custom LogFactory implementation ");</span>
-<span class="source-line-no">364</span><span id="line-364"> msg.append("should be used but Class '");</span>
-<span class="source-line-no">365</span><span id="line-365"> msg.append(factoryClassName);</span>
-<span class="source-line-no">366</span><span id="line-366"> msg.append("' cannot be converted to '");</span>
-<span class="source-line-no">367</span><span id="line-367"> msg.append(LogFactory.class.getName());</span>
-<span class="source-line-no">368</span><span id="line-368"> msg.append("'. ");</span>
-<span class="source-line-no">369</span><span id="line-369"> if (implementsLogFactory) {</span>
-<span class="source-line-no">370</span><span id="line-370"> msg.append("The conflict is caused by the presence of multiple LogFactory classes ");</span>
-<span class="source-line-no">371</span><span id="line-371"> msg.append("in incompatible class loaders. ");</span>
-<span class="source-line-no">372</span><span id="line-372"> msg.append("Background can be found in https://commons.apache.org/logging/tech.html. ");</span>
-<span class="source-line-no">373</span><span id="line-373"> msg.append("If you have not explicitly specified a custom LogFactory then it is likely ");</span>
-<span class="source-line-no">374</span><span id="line-374"> msg.append("that the container has set one without your knowledge. ");</span>
-<span class="source-line-no">375</span><span id="line-375"> msg.append("In this case, consider using the commons-logging-adapters.jar file or ");</span>
-<span class="source-line-no">376</span><span id="line-376"> msg.append("specifying the standard LogFactory from the command line. ");</span>
-<span class="source-line-no">377</span><span id="line-377"> } else {</span>
-<span class="source-line-no">378</span><span id="line-378"> msg.append("Please check the custom implementation. ");</span>
-<span class="source-line-no">379</span><span id="line-379"> }</span>
-<span class="source-line-no">380</span><span id="line-380"> msg.append("Help can be found at https://commons.apache.org/logging/troubleshooting.html.");</span>
-<span class="source-line-no">381</span><span id="line-381"></span>
-<span class="source-line-no">382</span><span id="line-382"> if (isDiagnosticsEnabled()) {</span>
-<span class="source-line-no">383</span><span id="line-383"> logDiagnostic(msg.toString());</span>
-<span class="source-line-no">384</span><span id="line-384"> }</span>
-<span class="source-line-no">385</span><span id="line-385"></span>
-<span class="source-line-no">386</span><span id="line-386"> throw new ClassCastException(msg.toString());</span>
-<span class="source-line-no">387</span><span id="line-387"> }</span>
-<span class="source-line-no">388</span><span id="line-388"></span>
-<span class="source-line-no">389</span><span id="line-389"> // Ignore exception, continue. Presumably the class loader was the</span>
-<span class="source-line-no">390</span><span id="line-390"> // TCCL; the code below will try to load the class via thisClassLoaderRef.</span>
-<span class="source-line-no">391</span><span id="line-391"> // This will handle the case where the original calling class is in</span>
-<span class="source-line-no">392</span><span id="line-392"> // a shared classpath but the TCCL has a copy of LogFactory and the</span>
-<span class="source-line-no">393</span><span id="line-393"> // specified LogFactory implementation; we will fall back to using the</span>
-<span class="source-line-no">394</span><span id="line-394"> // LogFactory implementation from the same class loader as this class.</span>
-<span class="source-line-no">395</span><span id="line-395"> //</span>
-<span class="source-line-no">396</span><span id="line-396"> // Issue: this doesn't handle the reverse case, where this LogFactory</span>
-<span class="source-line-no">397</span><span id="line-397"> // is in the webapp, and the specified LogFactory implementation is</span>
-<span class="source-line-no">398</span><span id="line-398"> // in a shared classpath. In that case:</span>
-<span class="source-line-no">399</span><span id="line-399"> // (a) the class really does implement LogFactory (bad log msg above)</span>
-<span class="source-line-no">400</span><span id="line-400"> // (b) the fallback code will result in exactly the same problem.</span>
-<span class="source-line-no">401</span><span id="line-401"> }</span>
-<span class="source-line-no">402</span><span id="line-402"> }</span>
-<span class="source-line-no">403</span><span id="line-403"></span>
-<span class="source-line-no">404</span><span id="line-404"> /*</span>
-<span class="source-line-no">405</span><span id="line-405"> * At this point, either classLoader == null, OR classLoader was unable to load factoryClass.</span>
-<span class="source-line-no">406</span><span id="line-406"> *</span>
-<span class="source-line-no">407</span><span id="line-407"> * In either case, we call Class.forName, which is equivalent to LogFactory.class.getClassLoader().load(name), that is, we ignore the class loader</span>
-<span class="source-line-no">408</span><span id="line-408"> * parameter the caller passed, and fall back to trying the class loader associated with this class. See the Javadoc for the newFactory method for</span>
-<span class="source-line-no">409</span><span id="line-409"> * more info on the consequences of this.</span>
-<span class="source-line-no">410</span><span id="line-410"> *</span>
-<span class="source-line-no">411</span><span id="line-411"> * Notes: * LogFactory.class.getClassLoader() may return 'null' if LogFactory is loaded by the bootstrap class loader.</span>
-<span class="source-line-no">412</span><span id="line-412"> */</span>
-<span class="source-line-no">413</span><span id="line-413"> // Warning: must typecast here & allow exception</span>
-<span class="source-line-no">414</span><span id="line-414"> // to be generated/caught & recast properly.</span>
-<span class="source-line-no">415</span><span id="line-415"> if (isDiagnosticsEnabled()) {</span>
-<span class="source-line-no">416</span><span id="line-416"> logDiagnostic(</span>
-<span class="source-line-no">417</span><span id="line-417"> "Unable to load factory class via class loader " + objectId(classLoader) + " - trying the class loader associated with this LogFactory.");</span>
-<span class="source-line-no">418</span><span id="line-418"> }</span>
-<span class="source-line-no">419</span><span id="line-419"> logFactoryClass = Class.forName(factoryClassName);</span>
-<span class="source-line-no">420</span><span id="line-420"> return logFactoryClass.newInstance();</span>
-<span class="source-line-no">421</span><span id="line-421"> } catch (final Exception e) {</span>
-<span class="source-line-no">422</span><span id="line-422"> // Check to see if we've got a bad configuration</span>
+<span class="source-line-no">046</span><span id="line-46"> * </p></span>
+<span class="source-line-no">047</span><span id="line-47"> */</span>
+<span class="source-line-no">048</span><span id="line-48">public abstract class LogFactory {</span>
+<span class="source-line-no">049</span><span id="line-49"> // Implementation note re AccessController usage</span>
+<span class="source-line-no">050</span><span id="line-50"> //</span>
+<span class="source-line-no">051</span><span id="line-51"> // It is important to keep code invoked via an AccessController to small</span>
+<span class="source-line-no">052</span><span id="line-52"> // auditable blocks. Such code must carefully evaluate all user input</span>
+<span class="source-line-no">053</span><span id="line-53"> // (parameters, system properties, configuration file contents, etc). As an</span>
+<span class="source-line-no">054</span><span id="line-54"> // example, a Log implementation should not write to its log file</span>
+<span class="source-line-no">055</span><span id="line-55"> // with an AccessController anywhere in the call stack, otherwise an</span>
+<span class="source-line-no">056</span><span id="line-56"> // insecure application could configure the log implementation to write</span>
+<span class="source-line-no">057</span><span id="line-57"> // to a protected file using the privileges granted to JCL rather than</span>
+<span class="source-line-no">058</span><span id="line-58"> // to the calling application.</span>
+<span class="source-line-no">059</span><span id="line-59"> //</span>
+<span class="source-line-no">060</span><span id="line-60"> // Under no circumstance should a non-private method return data that is</span>
+<span class="source-line-no">061</span><span id="line-61"> // retrieved via an AccessController. That would allow an insecure application</span>
+<span class="source-line-no">062</span><span id="line-62"> // to invoke that method and obtain data that it is not permitted to have.</span>
+<span class="source-line-no">063</span><span id="line-63"> //</span>
+<span class="source-line-no">064</span><span id="line-64"> // Invoking user-supplied code with an AccessController set is not a major</span>
+<span class="source-line-no">065</span><span id="line-65"> // issue (for example, invoking the constructor of the class specified by</span>
+<span class="source-line-no">066</span><span id="line-66"> // HASHTABLE_IMPLEMENTATION_PROPERTY). That class will be in a different</span>
+<span class="source-line-no">067</span><span id="line-67"> // trust domain, and therefore must have permissions to do whatever it</span>
+<span class="source-line-no">068</span><span id="line-68"> // is trying to do regardless of the permissions granted to JCL. There is</span>
+<span class="source-line-no">069</span><span id="line-69"> // a slight issue in that untrusted code may point that environment variable</span>
+<span class="source-line-no">070</span><span id="line-70"> // to another trusted library, in which case the code runs if both that</span>
+<span class="source-line-no">071</span><span id="line-71"> // library and JCL have the necessary permissions even when the untrusted</span>
+<span class="source-line-no">072</span><span id="line-72"> // caller does not. That's a pretty hard route to exploit though.</span>
+<span class="source-line-no">073</span><span id="line-73"></span>
+<span class="source-line-no">074</span><span id="line-74"> /**</span>
+<span class="source-line-no">075</span><span id="line-75"> * The name ({@code priority}) of the key in the configuration file used to</span>
+<span class="source-line-no">076</span><span id="line-76"> * specify the priority of that particular configuration file. The associated value</span>
+<span class="source-line-no">077</span><span id="line-77"> * is a floating-point number; higher values take priority over lower values.</span>
+<span class="source-line-no">078</span><span id="line-78"> */</span>
+<span class="source-line-no">079</span><span id="line-79"> public static final String PRIORITY_KEY = "priority";</span>
+<span class="source-line-no">080</span><span id="line-80"></span>
+<span class="source-line-no">081</span><span id="line-81"> /**</span>
+<span class="source-line-no">082</span><span id="line-82"> * The name ({@code use_tccl}) of the key in the configuration file used</span>
+<span class="source-line-no">083</span><span id="line-83"> * to specify whether logging classes should be loaded via the thread</span>
+<span class="source-line-no">084</span><span id="line-84"> * context class loader (TCCL), or not. By default, the TCCL is used.</span>
+<span class="source-line-no">085</span><span id="line-85"> */</span>
+<span class="source-line-no">086</span><span id="line-86"> public static final String TCCL_KEY = "use_tccl";</span>
+<span class="source-line-no">087</span><span id="line-87"></span>
+<span class="source-line-no">088</span><span id="line-88"> /**</span>
+<span class="source-line-no">089</span><span id="line-89"> * The name ({@code org.apache.commons.logging.LogFactory}) of the property</span>
+<span class="source-line-no">090</span><span id="line-90"> * used to identify the LogFactory implementation</span>
+<span class="source-line-no">091</span><span id="line-91"> * class name. This can be used as a system property, or as an entry in a</span>
+<span class="source-line-no">092</span><span id="line-92"> * configuration properties file.</span>
+<span class="source-line-no">093</span><span id="line-93"> */</span>
+<span class="source-line-no">094</span><span id="line-94"> public static final String FACTORY_PROPERTY = "org.apache.commons.logging.LogFactory";</span>
+<span class="source-line-no">095</span><span id="line-95"></span>
+<span class="source-line-no">096</span><span id="line-96"> private static final String FACTORY_LOG4J_API = "org.apache.commons.logging.impl.Log4jApiLogFactory";</span>
+<span class="source-line-no">097</span><span id="line-97"> private static final String LOG4J_API_LOGGER = "org.apache.logging.log4j.Logger";</span>
+<span class="source-line-no">098</span><span id="line-98"> private static final String LOG4J_TO_SLF4J_BRIDGE = "org.apache.logging.slf4j.SLF4JProvider";</span>
+<span class="source-line-no">099</span><span id="line-99"></span>
+<span class="source-line-no">100</span><span id="line-100"> private static final String FACTORY_SLF4J = "org.apache.commons.logging.impl.Slf4jLogFactory";</span>
+<span class="source-line-no">101</span><span id="line-101"> private static final String SLF4J_API_LOGGER = "org.slf4j.Logger";</span>
+<span class="source-line-no">102</span><span id="line-102"></span>
+<span class="source-line-no">103</span><span id="line-103"> /**</span>
+<span class="source-line-no">104</span><span id="line-104"> * The fully qualified class name of the fallback {@code LogFactory}</span>
+<span class="source-line-no">105</span><span id="line-105"> * implementation class to use, if no other can be found.</span>
+<span class="source-line-no">106</span><span id="line-106"> */</span>
+<span class="source-line-no">107</span><span id="line-107"> public static final String FACTORY_DEFAULT = "org.apache.commons.logging.impl.LogFactoryImpl";</span>
+<span class="source-line-no">108</span><span id="line-108"></span>
+<span class="source-line-no">109</span><span id="line-109"> /**</span>
+<span class="source-line-no">110</span><span id="line-110"> * The name ({@code commons-logging.properties}) of the properties file to search for.</span>
+<span class="source-line-no">111</span><span id="line-111"> */</span>
+<span class="source-line-no">112</span><span id="line-112"> public static final String FACTORY_PROPERTIES = "commons-logging.properties";</span>
+<span class="source-line-no">113</span><span id="line-113"></span>
+<span class="source-line-no">114</span><span id="line-114"> /**</span>
+<span class="source-line-no">115</span><span id="line-115"> * JDK 1.3+ <a href="https://java.sun.com/j2se/1.3/docs/guide/jar/jar.html#Service%20Provider"></span>
+<span class="source-line-no">116</span><span id="line-116"> * 'Service Provider' specification</a>.</span>
+<span class="source-line-no">117</span><span id="line-117"> */</span>
+<span class="source-line-no">118</span><span id="line-118"> protected static final String SERVICE_ID =</span>
+<span class="source-line-no">119</span><span id="line-119"> "META-INF/services/org.apache.commons.logging.LogFactory";</span>
+<span class="source-line-no">120</span><span id="line-120"></span>
+<span class="source-line-no">121</span><span id="line-121"> /**</span>
+<span class="source-line-no">122</span><span id="line-122"> * The name ({@code org.apache.commons.logging.diagnostics.dest})</span>
+<span class="source-line-no">123</span><span id="line-123"> * of the property used to enable internal commons-logging</span>
+<span class="source-line-no">124</span><span id="line-124"> * diagnostic output, in order to get information on what logging</span>
+<span class="source-line-no">125</span><span id="line-125"> * implementations are being discovered, what class loaders they</span>
+<span class="source-line-no">126</span><span id="line-126"> * are loaded through, etc.</span>
+<span class="source-line-no">127</span><span id="line-127"> * <p></span>
+<span class="source-line-no">128</span><span id="line-128"> * If a system property of this name is set then the value is</span>
+<span class="source-line-no">129</span><span id="line-129"> * assumed to be the name of a file. The special strings</span>
+<span class="source-line-no">130</span><span id="line-130"> * STDOUT or STDERR (case-sensitive) indicate output to</span>
+<span class="source-line-no">131</span><span id="line-131"> * System.out and System.err respectively.</span>
+<span class="source-line-no">132</span><span id="line-132"> * <p></span>
+<span class="source-line-no">133</span><span id="line-133"> * Diagnostic logging should be used only to debug problematic</span>
+<span class="source-line-no">134</span><span id="line-134"> * configurations and should not be set in normal production use.</span>
+<span class="source-line-no">135</span><span id="line-135"> */</span>
+<span class="source-line-no">136</span><span id="line-136"> public static final String DIAGNOSTICS_DEST_PROPERTY =</span>
+<span class="source-line-no">137</span><span id="line-137"> "org.apache.commons.logging.diagnostics.dest";</span>
+<span class="source-line-no">138</span><span id="line-138"></span>
+<span class="source-line-no">139</span><span id="line-139"> /**</span>
+<span class="source-line-no">140</span><span id="line-140"> * When null (the usual case), no diagnostic output will be</span>
+<span class="source-line-no">141</span><span id="line-141"> * generated by LogFactory or LogFactoryImpl. When non-null,</span>
+<span class="source-line-no">142</span><span id="line-142"> * interesting events will be written to the specified object.</span>
+<span class="source-line-no">143</span><span id="line-143"> */</span>
+<span class="source-line-no">144</span><span id="line-144"> private static final PrintStream DIAGNOSTICS_STREAM;</span>
+<span class="source-line-no">145</span><span id="line-145"></span>
+<span class="source-line-no">146</span><span id="line-146"> /**</span>
+<span class="source-line-no">147</span><span id="line-147"> * A string that gets prefixed to every message output by the</span>
+<span class="source-line-no">148</span><span id="line-148"> * logDiagnostic method, so that users can clearly see which</span>
+<span class="source-line-no">149</span><span id="line-149"> * LogFactory class is generating the output.</span>
+<span class="source-line-no">150</span><span id="line-150"> */</span>
+<span class="source-line-no">151</span><span id="line-151"> private static final String diagnosticPrefix;</span>
+<span class="source-line-no">152</span><span id="line-152"></span>
+<span class="source-line-no">153</span><span id="line-153"> /**</span>
+<span class="source-line-no">154</span><span id="line-154"> * Setting this system property</span>
+<span class="source-line-no">155</span><span id="line-155"> * ({@code org.apache.commons.logging.LogFactory.HashtableImpl})</span>
+<span class="source-line-no">156</span><span id="line-156"> * value allows the {@code Hashtable} used to store</span>
+<span class="source-line-no">157</span><span id="line-157"> * class loaders to be substituted by an alternative implementation.</span>
+<span class="source-line-no">158</span><span id="line-158"> * <p></span>
+<span class="source-line-no">159</span><span id="line-159"> * <strong>Note:</strong> {@code LogFactory} will print:</span>
+<span class="source-line-no">160</span><span id="line-160"> * </p></span>
+<span class="source-line-no">161</span><span id="line-161"> * <pre></span>
+<span class="source-line-no">162</span><span id="line-162"> * [ERROR] LogFactory: Load of custom hashtable failed</span>
+<span class="source-line-no">163</span><span id="line-163"> * </pre></span>
+<span class="source-line-no">164</span><span id="line-164"> * <p></span>
+<span class="source-line-no">165</span><span id="line-165"> * to system error and then continue using a standard Hashtable.</span>
+<span class="source-line-no">166</span><span id="line-166"> * </p></span>
+<span class="source-line-no">167</span><span id="line-167"> * <p></span>
+<span class="source-line-no">168</span><span id="line-168"> * <strong>Usage:</strong> Set this property when Java is invoked</span>
+<span class="source-line-no">169</span><span id="line-169"> * and {@code LogFactory} will attempt to load a new instance</span>
+<span class="source-line-no">170</span><span id="line-170"> * of the given implementation class.</span>
+<span class="source-line-no">171</span><span id="line-171"> * For example, running the following ant scriplet:</span>
+<span class="source-line-no">172</span><span id="line-172"> * </p></span>
+<span class="source-line-no">173</span><span id="line-173"> * <pre></span>
+<span class="source-line-no">174</span><span id="line-174"> * &lt;java classname="${test.runner}" fork="yes" failonerror="${test.failonerror}"&gt;</span>
+<span class="source-line-no">175</span><span id="line-175"> * ...</span>
+<span class="source-line-no">176</span><span id="line-176"> * &lt;sysproperty</span>
+<span class="source-line-no">177</span><span id="line-177"> * key="org.apache.commons.logging.LogFactory.HashtableImpl"</span>
+<span class="source-line-no">178</span><span id="line-178"> * value="org.apache.commons.logging.AltHashtable"/&gt;</span>
+<span class="source-line-no">179</span><span id="line-179"> * &lt;/java&gt;</span>
+<span class="source-line-no">180</span><span id="line-180"> * </pre></span>
+<span class="source-line-no">181</span><span id="line-181"> * <p></span>
+<span class="source-line-no">182</span><span id="line-182"> * will mean that {@code LogFactory} will load an instance of</span>
+<span class="source-line-no">183</span><span id="line-183"> * {@code org.apache.commons.logging.AltHashtable}.</span>
+<span class="source-line-no">184</span><span id="line-184"> * </p></span>
+<span class="source-line-no">185</span><span id="line-185"> * <p></span>
+<span class="source-line-no">186</span><span id="line-186"> * A typical use case is to allow a custom</span>
+<span class="source-line-no">187</span><span id="line-187"> * Hashtable implementation using weak references to be substituted.</span>
+<span class="source-line-no">188</span><span id="line-188"> * This will allow class loaders to be garbage collected without</span>
+<span class="source-line-no">189</span><span id="line-189"> * the need to release them (on 1.3+ JVMs only, of course ;).</span>
+<span class="source-line-no">190</span><span id="line-190"> * </p></span>
+<span class="source-line-no">191</span><span id="line-191"> */</span>
+<span class="source-line-no">192</span><span id="line-192"> public static final String HASHTABLE_IMPLEMENTATION_PROPERTY =</span>
+<span class="source-line-no">193</span><span id="line-193"> "org.apache.commons.logging.LogFactory.HashtableImpl";</span>
+<span class="source-line-no">194</span><span id="line-194"></span>
+<span class="source-line-no">195</span><span id="line-195"> /** Name used to load the weak hashtable implementation by names. */</span>
+<span class="source-line-no">196</span><span id="line-196"> private static final String WEAK_HASHTABLE_CLASSNAME =</span>
+<span class="source-line-no">197</span><span id="line-197"> "org.apache.commons.logging.impl.WeakHashtable";</span>
+<span class="source-line-no">198</span><span id="line-198"></span>
+<span class="source-line-no">199</span><span id="line-199"> /**</span>
+<span class="source-line-no">200</span><span id="line-200"> * A reference to the class loader that loaded this class. This is the</span>
+<span class="source-line-no">201</span><span id="line-201"> * same as LogFactory.class.getClassLoader(). However computing this</span>
+<span class="source-line-no">202</span><span id="line-202"> * value isn't quite as simple as that, as we potentially need to use</span>
+<span class="source-line-no">203</span><span id="line-203"> * AccessControllers etc. It's more efficient to compute it once and</span>
+<span class="source-line-no">204</span><span id="line-204"> * cache it here.</span>
+<span class="source-line-no">205</span><span id="line-205"> */</span>
+<span class="source-line-no">206</span><span id="line-206"> private static final WeakReference<ClassLoader> thisClassLoaderRef;</span>
+<span class="source-line-no">207</span><span id="line-207"></span>
+<span class="source-line-no">208</span><span id="line-208"> /**</span>
+<span class="source-line-no">209</span><span id="line-209"> * Maximum number of {@link ServiceLoader} errors to ignore, while</span>
+<span class="source-line-no">210</span><span id="line-210"> * looking for an implementation.</span>
+<span class="source-line-no">211</span><span id="line-211"> */</span>
+<span class="source-line-no">212</span><span id="line-212"> private static final int MAX_BROKEN_SERVICES = 3;</span>
+<span class="source-line-no">213</span><span id="line-213"></span>
+<span class="source-line-no">214</span><span id="line-214"> /**</span>
+<span class="source-line-no">215</span><span id="line-215"> * The previously constructed {@code LogFactory} instances, keyed by</span>
+<span class="source-line-no">216</span><span id="line-216"> * the {@code ClassLoader} with which it was created.</span>
+<span class="source-line-no">217</span><span id="line-217"> */</span>
+<span class="source-line-no">218</span><span id="line-218"> protected static Hashtable<ClassLoader, LogFactory> factories;</span>
+<span class="source-line-no">219</span><span id="line-219"></span>
+<span class="source-line-no">220</span><span id="line-220"> /**</span>
+<span class="source-line-no">221</span><span id="line-221"> * Previously constructed {@code LogFactory} instance as in the</span>
+<span class="source-line-no">222</span><span id="line-222"> * {@code factories} map, but for the case where</span>
+<span class="source-line-no">223</span><span id="line-223"> * {@code getClassLoader} returns {@code null}.</span>
+<span class="source-line-no">224</span><span id="line-224"> * This can happen when:</span>
+<span class="source-line-no">225</span><span id="line-225"> * <ul></span>
+<span class="source-line-no">226</span><span id="line-226"> * <li>using JDK1.1 and the calling code is loaded via the system</span>
+<span class="source-line-no">227</span><span id="line-227"> * class loader (very common)</li></span>
+<span class="source-line-no">228</span><span id="line-228"> * <li>using JDK1.2+ and the calling code is loaded via the boot</span>
+<span class="source-line-no">229</span><span id="line-229"> * class loader (only likely for embedded systems work).</li></span>
+<span class="source-line-no">230</span><span id="line-230"> * </ul></span>
+<span class="source-line-no">231</span><span id="line-231"> * Note that {@code factories} is a <i>Hashtable</i> (not a HashMap),</span>
+<span class="source-line-no">232</span><span id="line-232"> * and hashtables don't allow null as a key.</span>
+<span class="source-line-no">233</span><span id="line-233"> * @deprecated since 1.1.2</span>
+<span class="source-line-no">234</span><span id="line-234"> */</span>
+<span class="source-line-no">235</span><span id="line-235"> @Deprecated</span>
+<span class="source-line-no">236</span><span id="line-236"> protected static volatile LogFactory nullClassLoaderFactory;</span>
+<span class="source-line-no">237</span><span id="line-237"></span>
+<span class="source-line-no">238</span><span id="line-238"> static {</span>
+<span class="source-line-no">239</span><span id="line-239"> // note: it's safe to call methods before initDiagnostics (though</span>
+<span class="source-line-no">240</span><span id="line-240"> // diagnostic output gets discarded).</span>
+<span class="source-line-no">241</span><span id="line-241"> final ClassLoader thisClassLoader = getClassLoader(LogFactory.class);</span>
+<span class="source-line-no">242</span><span id="line-242"> thisClassLoaderRef = new WeakReference<>(thisClassLoader);</span>
+<span class="source-line-no">243</span><span id="line-243"> // In order to avoid confusion where multiple instances of JCL are</span>
+<span class="source-line-no">244</span><span id="line-244"> // being used via different class loaders within the same app, we</span>
+<span class="source-line-no">245</span><span id="line-245"> // ensure each logged message has a prefix of form</span>
+<span class="source-line-no">246</span><span id="line-246"> // [LogFactory from class loader OID]</span>
+<span class="source-line-no">247</span><span id="line-247"> //</span>
+<span class="source-line-no">248</span><span id="line-248"> // Note that this prefix should be kept consistent with that</span>
+<span class="source-line-no">249</span><span id="line-249"> // in LogFactoryImpl. However here we don't need to output info</span>
+<span class="source-line-no">250</span><span id="line-250"> // about the actual *instance* of LogFactory, as all methods that</span>
+<span class="source-line-no">251</span><span id="line-251"> // output diagnostics from this class are static.</span>
+<span class="source-line-no">252</span><span id="line-252"> String classLoaderName;</span>
+<span class="source-line-no">253</span><span id="line-253"> try {</span>
+<span class="source-line-no">254</span><span id="line-254"> if (thisClassLoader == null) {</span>
+<span class="source-line-no">255</span><span id="line-255"> classLoaderName = "BOOTLOADER";</span>
+<span class="source-line-no">256</span><span id="line-256"> } else {</span>
+<span class="source-line-no">257</span><span id="line-257"> classLoaderName = objectId(thisClassLoader);</span>
+<span class="source-line-no">258</span><span id="line-258"> }</span>
+<span class="source-line-no">259</span><span id="line-259"> } catch (final SecurityException e) {</span>
+<span class="source-line-no">260</span><span id="line-260"> classLoaderName = "UNKNOWN";</span>
+<span class="source-line-no">261</span><span id="line-261"> }</span>
+<span class="source-line-no">262</span><span id="line-262"> diagnosticPrefix = "[LogFactory from " + classLoaderName + "] ";</span>
+<span class="source-line-no">263</span><span id="line-263"> DIAGNOSTICS_STREAM = initDiagnostics();</span>
+<span class="source-line-no">264</span><span id="line-264"> logClassLoaderEnvironment(LogFactory.class);</span>
+<span class="source-line-no">265</span><span id="line-265"> factories = createFactoryStore();</span>
+<span class="source-line-no">266</span><span id="line-266"> if (isDiagnosticsEnabled()) {</span>
+<span class="source-line-no">267</span><span id="line-267"> logDiagnostic("BOOTSTRAP COMPLETED");</span>
+<span class="source-line-no">268</span><span id="line-268"> }</span>
+<span class="source-line-no">269</span><span id="line-269"> }</span>
+<span class="source-line-no">270</span><span id="line-270"></span>
+<span class="source-line-no">271</span><span id="line-271"> /**</span>
+<span class="source-line-no">272</span><span id="line-272"> * Remember this factory, so later calls to LogFactory.getCachedFactory</span>
+<span class="source-line-no">273</span><span id="line-273"> * can return the previously created object (together with all its</span>
+<span class="source-line-no">274</span><span id="line-274"> * cached Log objects).</span>
+<span class="source-line-no">275</span><span id="line-275"> *</span>
+<span class="source-line-no">276</span><span id="line-276"> * @param classLoader should be the current context class loader. Note that</span>
+<span class="source-line-no">277</span><span id="line-277"> * this can be null under some circumstances; this is ok.</span>
+<span class="source-line-no">278</span><span id="line-278"> * @param factory should be the factory to cache. This should never be null.</span>
+<span class="source-line-no">279</span><span id="line-279"> */</span>
+<span class="source-line-no">280</span><span id="line-280"> private static void cacheFactory(final ClassLoader classLoader, final LogFactory factory) {</span>
+<span class="source-line-no">281</span><span id="line-281"> // Ideally we would assert(factory != null) here. However reporting</span>
+<span class="source-line-no">282</span><span id="line-282"> // errors from within a logging implementation is a little tricky!</span>
+<span class="source-line-no">283</span><span id="line-283"></span>
+<span class="source-line-no">284</span><span id="line-284"> if (factory != null) {</span>
+<span class="source-line-no">285</span><span id="line-285"> if (classLoader == null) {</span>
+<span class="source-line-no">286</span><span id="line-286"> nullClassLoaderFactory = factory;</span>
+<span class="source-line-no">287</span><span id="line-287"> } else {</span>
+<span class="source-line-no">288</span><span id="line-288"> factories.put(classLoader, factory);</span>
+<span class="source-line-no">289</span><span id="line-289"> }</span>
+<span class="source-line-no">290</span><span id="line-290"> }</span>
+<span class="source-line-no">291</span><span id="line-291"> }</span>
+<span class="source-line-no">292</span><span id="line-292"></span>
+<span class="source-line-no">293</span><span id="line-293"> /**</span>
+<span class="source-line-no">294</span><span id="line-294"> * Implements the operations described in the Javadoc for newFactory.</span>
+<span class="source-line-no">295</span><span id="line-295"> *</span>
+<span class="source-line-no">296</span><span id="line-296"> * @param factoryClassName Factory class.</span>
+<span class="source-line-no">297</span><span id="line-297"> * @param classLoader used to load the specified factory class. This is expected to be either the TCCL or the class loader which loaded this class.</span>
+<span class="source-line-no">298</span><span id="line-298"> * Note that the class loader which loaded this class might be "null" (for example, the boot loader) for embedded systems.</span>
+<span class="source-line-no">299</span><span id="line-299"> * @return either a LogFactory object or a LogConfigurationException object.</span>
+<span class="source-line-no">300</span><span id="line-300"> * @since 1.1</span>
+<span class="source-line-no">301</span><span id="line-301"> */</span>
+<span class="source-line-no">302</span><span id="line-302"> protected static Object createFactory(final String factoryClassName, final ClassLoader classLoader) {</span>
+<span class="source-line-no">303</span><span id="line-303"> // This will be used to diagnose bad configurations</span>
+<span class="source-line-no">304</span><span id="line-304"> // and allow a useful message to be sent to the user</span>
+<span class="source-line-no">305</span><span id="line-305"> Class<?> logFactoryClass = null;</span>
+<span class="source-line-no">306</span><span id="line-306"> try {</span>
+<span class="source-line-no">307</span><span id="line-307"> if (classLoader != null) {</span>
+<span class="source-line-no">308</span><span id="line-308"> try {</span>
+<span class="source-line-no">309</span><span id="line-309"> // First the given class loader param (thread class loader)</span>
+<span class="source-line-no">310</span><span id="line-310"></span>
+<span class="source-line-no">311</span><span id="line-311"> // Warning: must typecast here & allow exception</span>
+<span class="source-line-no">312</span><span id="line-312"> // to be generated/caught & recast properly.</span>
+<span class="source-line-no">313</span><span id="line-313"> logFactoryClass = classLoader.loadClass(factoryClassName);</span>
+<span class="source-line-no">314</span><span id="line-314"> if (LogFactory.class.isAssignableFrom(logFactoryClass)) {</span>
+<span class="source-line-no">315</span><span id="line-315"> if (isDiagnosticsEnabled()) {</span>
+<span class="source-line-no">316</span><span id="line-316"> logDiagnostic("Loaded class " + logFactoryClass.getName() + " from class loader " + objectId(classLoader));</span>
+<span class="source-line-no">317</span><span id="line-317"> }</span>
+<span class="source-line-no">318</span><span id="line-318"> } else //</span>
+<span class="source-line-no">319</span><span id="line-319"> // This indicates a problem with the ClassLoader tree.</span>
+<span class="source-line-no">320</span><span id="line-320"> // An incompatible ClassLoader was used to load the</span>
+<span class="source-line-no">321</span><span id="line-321"> // implementation.</span>
+<span class="source-line-no">322</span><span id="line-322"> // As the same classes</span>
+<span class="source-line-no">323</span><span id="line-323"> // must be available in multiple class loaders,</span>
+<span class="source-line-no">324</span><span id="line-324"> // it is very likely that multiple JCL jars are present.</span>
+<span class="source-line-no">325</span><span id="line-325"> // The most likely fix for this</span>
+<span class="source-line-no">326</span><span id="line-326"> // problem is to remove the extra JCL jars from the</span>
+<span class="source-line-no">327</span><span id="line-327"> // ClassLoader hierarchy.</span>
+<span class="source-line-no">328</span><span id="line-328"> //</span>
+<span class="source-line-no">329</span><span id="line-329"> if (isDiagnosticsEnabled()) {</span>
+<span class="source-line-no">330</span><span id="line-330"> logDiagnostic("Factory class " + logFactoryClass.getName() + " loaded from class loader " + objectId(logFactoryClass.getClassLoader())</span>
+<span class="source-line-no">331</span><span id="line-331"> + " does not extend '" + LogFactory.class.getName() + "' as loaded by this class loader.");</span>
+<span class="source-line-no">332</span><span id="line-332"> logHierarchy("[BAD CL TREE] ", classLoader);</span>
+<span class="source-line-no">333</span><span id="line-333"> }</span>
+<span class="source-line-no">334</span><span id="line-334"></span>
+<span class="source-line-no">335</span><span id="line-335"> return logFactoryClass.getConstructor().newInstance();</span>
+<span class="source-line-no">336</span><span id="line-336"></span>
+<span class="source-line-no">337</span><span id="line-337"> } catch (final ClassNotFoundException ex) {</span>
+<span class="source-line-no">338</span><span id="line-338"> if (classLoader == thisClassLoaderRef.get()) {</span>
+<span class="source-line-no">339</span><span id="line-339"> // Nothing more to try, onwards.</span>
+<span class="source-line-no">340</span><span id="line-340"> if (isDiagnosticsEnabled()) {</span>
+<span class="source-line-no">341</span><span id="line-341"> logDiagnostic("Unable to locate any class called '" + factoryClassName + "' via class loader " + objectId(classLoader));</span>
+<span class="source-line-no">342</span><span id="line-342"> }</span>
+<span class="source-line-no">343</span><span id="line-343"> throw ex;</span>
+<span class="source-line-no">344</span><span id="line-344"> }</span>
+<span class="source-line-no">345</span><span id="line-345"> // ignore exception, continue</span>
+<span class="source-line-no">346</span><span id="line-346"> } catch (final NoClassDefFoundError e) {</span>
+<span class="source-line-no">347</span><span id="line-347"> if (classLoader == thisClassLoaderRef.get()) {</span>
+<span class="source-line-no">348</span><span id="line-348"> // Nothing more to try, onwards.</span>
+<span class="source-line-no">349</span><span id="line-349"> if (isDiagnosticsEnabled()) {</span>
+<span class="source-line-no">350</span><span id="line-350"> logDiagnostic("Class '" + factoryClassName + "' cannot be loaded" + " via class loader " + objectId(classLoader)</span>
+<span class="source-line-no">351</span><span id="line-351"> + " - it depends on some other class that cannot be found.");</span>
+<span class="source-line-no">352</span><span id="line-352"> }</span>
+<span class="source-line-no">353</span><span id="line-353"> throw e;</span>
+<span class="source-line-no">354</span><span id="line-354"> }</span>
+<span class="source-line-no">355</span><span id="line-355"> // ignore exception, continue</span>
+<span class="source-line-no">356</span><span id="line-356"> } catch (final ClassCastException e) {</span>
+<span class="source-line-no">357</span><span id="line-357"> if (classLoader == thisClassLoaderRef.get()) {</span>
+<span class="source-line-no">358</span><span id="line-358"> // There's no point in falling through to the code below that</span>
+<span class="source-line-no">359</span><span id="line-359"> // tries again with thisClassLoaderRef, because we've just tried</span>
+<span class="source-line-no">360</span><span id="line-360"> // loading with that loader (not the TCCL). Just throw an</span>
+<span class="source-line-no">361</span><span id="line-361"> // appropriate exception here.</span>
+<span class="source-line-no">362</span><span id="line-362"></span>
+<span class="source-line-no">363</span><span id="line-363"> final boolean implementsLogFactory = implementsLogFactory(logFactoryClass);</span>
+<span class="source-line-no">364</span><span id="line-364"></span>
+<span class="source-line-no">365</span><span id="line-365"> //</span>
+<span class="source-line-no">366</span><span id="line-366"> // Construct a good message: users may not actual expect that a custom implementation</span>
+<span class="source-line-no">367</span><span id="line-367"> // has been specified. Several well known containers use this mechanism to adapt JCL</span>
+<span class="source-line-no">368</span><span id="line-368"> // to their native logging system.</span>
+<span class="source-line-no">369</span><span id="line-369"> //</span>
+<span class="source-line-no">370</span><span id="line-370"> final StringBuilder msg = new StringBuilder();</span>
+<span class="source-line-no">371</span><span id="line-371"> msg.append("The application has specified that a custom LogFactory implementation ");</span>
+<span class="source-line-no">372</span><span id="line-372"> msg.append("should be used but Class '");</span>
+<span class="source-line-no">373</span><span id="line-373"> msg.append(factoryClassName);</span>
+<span class="source-line-no">374</span><span id="line-374"> msg.append("' cannot be converted to '");</span>
+<span class="source-line-no">375</span><span id="line-375"> msg.append(LogFactory.class.getName());</span>
+<span class="source-line-no">376</span><span id="line-376"> msg.append("'. ");</span>
+<span class="source-line-no">377</span><span id="line-377"> if (implementsLogFactory) {</span>
+<span class="source-line-no">378</span><span id="line-378"> msg.append("The conflict is caused by the presence of multiple LogFactory classes ");</span>
+<span class="source-line-no">379</span><span id="line-379"> msg.append("in incompatible class loaders. ");</span>
+<span class="source-line-no">380</span><span id="line-380"> msg.append("Background can be found in https://commons.apache.org/logging/tech.html. ");</span>
+<span class="source-line-no">381</span><span id="line-381"> msg.append("If you have not explicitly specified a custom LogFactory then it is likely ");</span>
+<span class="source-line-no">382</span><span id="line-382"> msg.append("that the container has set one without your knowledge. ");</span>
+<span class="source-line-no">383</span><span id="line-383"> msg.append("In this case, consider using the commons-logging-adapters.jar file or ");</span>
+<span class="source-line-no">384</span><span id="line-384"> msg.append("specifying the standard LogFactory from the command line. ");</span>
+<span class="source-line-no">385</span><span id="line-385"> } else {</span>
+<span class="source-line-no">386</span><span id="line-386"> msg.append("Please check the custom implementation. ");</span>
+<span class="source-line-no">387</span><span id="line-387"> }</span>
+<span class="source-line-no">388</span><span id="line-388"> msg.append("Help can be found at https://commons.apache.org/logging/troubleshooting.html.");</span>
+<span class="source-line-no">389</span><span id="line-389"></span>
+<span class="source-line-no">390</span><span id="line-390"> if (isDiagnosticsEnabled()) {</span>
+<span class="source-line-no">391</span><span id="line-391"> logDiagnostic(msg.toString());</span>
+<span class="source-line-no">392</span><span id="line-392"> }</span>
+<span class="source-line-no">393</span><span id="line-393"></span>
+<span class="source-line-no">394</span><span id="line-394"> throw new ClassCastException(msg.toString());</span>
+<span class="source-line-no">395</span><span id="line-395"> }</span>
+<span class="source-line-no">396</span><span id="line-396"></span>
+<span class="source-line-no">397</span><span id="line-397"> // Ignore exception, continue. Presumably the class loader was the</span>
+<span class="source-line-no">398</span><span id="line-398"> // TCCL; the code below will try to load the class via thisClassLoaderRef.</span>
+<span class="source-line-no">399</span><span id="line-399"> // This will handle the case where the original calling class is in</span>
+<span class="source-line-no">400</span><span id="line-400"> // a shared classpath but the TCCL has a copy of LogFactory and the</span>
+<span class="source-line-no">401</span><span id="line-401"> // specified LogFactory implementation; we will fall back to using the</span>
+<span class="source-line-no">402</span><span id="line-402"> // LogFactory implementation from the same class loader as this class.</span>
+<span class="source-line-no">403</span><span id="line-403"> //</span>
+<span class="source-line-no">404</span><span id="line-404"> // Issue: this doesn't handle the reverse case, where this LogFactory</span>
+<span class="source-line-no">405</span><span id="line-405"> // is in the webapp, and the specified LogFactory implementation is</span>
+<span class="source-line-no">406</span><span id="line-406"> // in a shared classpath. In that case:</span>
+<span class="source-line-no">407</span><span id="line-407"> // (a) the class really does implement LogFactory (bad log msg above)</span>
+<span class="source-line-no">408</span><span id="line-408"> // (b) the fallback code will result in exactly the same problem.</span>
+<span class="source-line-no">409</span><span id="line-409"> }</span>
+<span class="source-line-no">410</span><span id="line-410"> }</span>
+<span class="source-line-no">411</span><span id="line-411"></span>
+<span class="source-line-no">412</span><span id="line-412"> /*</span>
+<span class="source-line-no">413</span><span id="line-413"> * At this point, either classLoader == null, OR classLoader was unable to load factoryClass.</span>
+<span class="source-line-no">414</span><span id="line-414"> *</span>
+<span class="source-line-no">415</span><span id="line-415"> * In either case, we call Class.forName, which is equivalent to LogFactory.class.getClassLoader().load(name), that is, we ignore the class loader</span>
+<span class="source-line-no">416</span><span id="line-416"> * parameter the caller passed, and fall back to trying the class loader associated with this class. See the Javadoc for the newFactory method for</span>
+<span class="source-line-no">417</span><span id="line-417"> * more info on the consequences of this.</span>
+<span class="source-line-no">418</span><span id="line-418"> *</span>
[... 2410 lines stripped ...]