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/03/24 17:59:14 UTC
svn commit: r1085996 [8/29] - 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/impl/LogFactoryImpl.html
==============================================================================
--- websites/production/commons/content/proper/commons-logging/apidocs/src-html/org/apache/commons/logging/impl/LogFactoryImpl.html (original)
+++ websites/production/commons/content/proper/commons-logging/apidocs/src-html/org/apache/commons/logging/impl/LogFactoryImpl.html Sun Mar 24 17:59:10 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.impl, class: LogFactoryImpl">
@@ -276,12 +276,12 @@
<span class="source-line-no">263</span><span id="line-263"> * This value is initialized by {@code getLogConstructor()},</span>
<span class="source-line-no">264</span><span id="line-264"> * and then returned repeatedly.</span>
<span class="source-line-no">265</span><span id="line-265"> */</span>
-<span class="source-line-no">266</span><span id="line-266"> protected Constructor logConstructor;</span>
+<span class="source-line-no">266</span><span id="line-266"> protected Constructor<?> logConstructor;</span>
<span class="source-line-no">267</span><span id="line-267"></span>
<span class="source-line-no">268</span><span id="line-268"> /**</span>
<span class="source-line-no">269</span><span id="line-269"> * The signature of the Constructor to be used.</span>
<span class="source-line-no">270</span><span id="line-270"> */</span>
-<span class="source-line-no">271</span><span id="line-271"> protected Class[] logConstructorSignature = { String.class };</span>
+<span class="source-line-no">271</span><span id="line-271"> protected Class<?>[] logConstructorSignature = { String.class };</span>
<span class="source-line-no">272</span><span id="line-272"></span>
<span class="source-line-no">273</span><span id="line-273"> /**</span>
<span class="source-line-no">274</span><span id="line-274"> * The one-argument {@code setLogFactory} method of the selected</span>
@@ -292,7 +292,7 @@
<span class="source-line-no">279</span><span id="line-279"> /**</span>
<span class="source-line-no">280</span><span id="line-280"> * The signature of the {@code setLogFactory} method to be used.</span>
<span class="source-line-no">281</span><span id="line-281"> */</span>
-<span class="source-line-no">282</span><span id="line-282"> protected Class[] logMethodSignature = { LogFactory.class };</span>
+<span class="source-line-no">282</span><span id="line-282"> protected Class<?>[] logMethodSignature = { LogFactory.class };</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"> * See getBaseClassLoader and initConfiguration.</span>
@@ -344,9 +344,9 @@
<span class="source-line-no">331</span><span id="line-331"></span>
<span class="source-line-no">332</span><span id="line-332"> final Object[] params = { logCategory };</span>
<span class="source-line-no">333</span><span id="line-333"> Log logAdapter = null;</span>
-<span class="source-line-no">334</span><span id="line-334"> Constructor constructor = null;</span>
+<span class="source-line-no">334</span><span id="line-334"> Constructor<?> constructor = null;</span>
<span class="source-line-no">335</span><span id="line-335"></span>
-<span class="source-line-no">336</span><span id="line-336"> Class logAdapterClass = null;</span>
+<span class="source-line-no">336</span><span id="line-336"> Class<?> logAdapterClass = null;</span>
<span class="source-line-no">337</span><span id="line-337"> ClassLoader currentCL = getBaseClassLoader();</span>
<span class="source-line-no">338</span><span id="line-338"></span>
<span class="source-line-no">339</span><span id="line-339"> for(;;) {</span>
@@ -374,7 +374,7 @@
<span class="source-line-no">361</span><span id="line-361"> }</span>
<span class="source-line-no">362</span><span id="line-362"> }</span>
<span class="source-line-no">363</span><span id="line-363"></span>
-<span class="source-line-no">364</span><span id="line-364"> Class clazz;</span>
+<span class="source-line-no">364</span><span id="line-364"> Class<?> clazz;</span>
<span class="source-line-no">365</span><span id="line-365"> try {</span>
<span class="source-line-no">366</span><span id="line-366"> clazz = Class.forName(logAdapterClassName, true, currentCL);</span>
<span class="source-line-no">367</span><span id="line-367"> } catch (final ClassNotFoundException originalClassNotFoundException) {</span>
@@ -653,7 +653,7 @@
<span class="source-line-no">640</span><span id="line-640"> }</span>
<span class="source-line-no">641</span><span id="line-641"></span>
<span class="source-line-no">642</span><span id="line-642"> /**</span>
-<span class="source-line-no">643</span><span id="line-643"> * Return the configuration attribute with the specified name (if any),</span>
+<span class="source-line-no">643</span><span id="line-643"> * Gets the configuration attribute with the specified name (if any),</span>
<span class="source-line-no">644</span><span id="line-644"> * or {@code null} if there is no such attribute.</span>
<span class="source-line-no">645</span><span id="line-645"> *</span>
<span class="source-line-no">646</span><span id="line-646"> * @param name Name of the attribute to return</span>
@@ -664,7 +664,7 @@
<span class="source-line-no">651</span><span id="line-651"> }</span>
<span class="source-line-no">652</span><span id="line-652"></span>
<span class="source-line-no">653</span><span id="line-653"> /**</span>
-<span class="source-line-no">654</span><span id="line-654"> * Return an array containing the names of all currently defined</span>
+<span class="source-line-no">654</span><span id="line-654"> * Gets an array containing the names of all currently defined</span>
<span class="source-line-no">655</span><span id="line-655"> * configuration attributes. If there are no such attributes, a zero</span>
<span class="source-line-no">656</span><span id="line-656"> * length array is returned.</span>
<span class="source-line-no">657</span><span id="line-657"> */</span>
@@ -674,7 +674,7 @@
<span class="source-line-no">661</span><span id="line-661"> }</span>
<span class="source-line-no">662</span><span id="line-662"></span>
<span class="source-line-no">663</span><span id="line-663"> /**</span>
-<span class="source-line-no">664</span><span id="line-664"> * Return the class loader from which we should try to load the logging</span>
+<span class="source-line-no">664</span><span id="line-664"> * Gets the class loader from which we should try to load the logging</span>
<span class="source-line-no">665</span><span id="line-665"> * adapter classes.</span>
<span class="source-line-no">666</span><span id="line-666"> * <p></span>
<span class="source-line-no">667</span><span id="line-667"> * This method usually returns the context class loader. However if it</span>
@@ -689,489 +689,489 @@
<span class="source-line-no">676</span><span id="line-676"> * failed to correctly set the context class loader. This is a bug in</span>
<span class="source-line-no">677</span><span id="line-677"> * the calling application; however we provide the option for JCL to</span>
<span class="source-line-no">678</span><span id="line-678"> * simply generate a warning rather than fail outright.</span>
-<span class="source-line-no">679</span><span id="line-679"> *</span>
-<span class="source-line-no">680</span><span id="line-680"> */</span>
-<span class="source-line-no">681</span><span id="line-681"> private ClassLoader getBaseClassLoader() throws LogConfigurationException {</span>
-<span class="source-line-no">682</span><span id="line-682"> final ClassLoader thisClassLoader = getClassLoader(LogFactoryImpl.class);</span>
-<span class="source-line-no">683</span><span id="line-683"></span>
-<span class="source-line-no">684</span><span id="line-684"> if (!useTCCL) {</span>
-<span class="source-line-no">685</span><span id="line-685"> return thisClassLoader;</span>
-<span class="source-line-no">686</span><span id="line-686"> }</span>
-<span class="source-line-no">687</span><span id="line-687"></span>
-<span class="source-line-no">688</span><span id="line-688"> final ClassLoader contextClassLoader = getContextClassLoaderInternal();</span>
-<span class="source-line-no">689</span><span id="line-689"></span>
-<span class="source-line-no">690</span><span id="line-690"> final ClassLoader baseClassLoader = getLowestClassLoader(</span>
-<span class="source-line-no">691</span><span id="line-691"> contextClassLoader, thisClassLoader);</span>
-<span class="source-line-no">692</span><span id="line-692"></span>
-<span class="source-line-no">693</span><span id="line-693"> if (baseClassLoader == null) {</span>
-<span class="source-line-no">694</span><span id="line-694"> // The two class loaders are not part of a parent child relationship.</span>
-<span class="source-line-no">695</span><span id="line-695"> // In some classloading setups (e.g. JBoss with its</span>
-<span class="source-line-no">696</span><span id="line-696"> // UnifiedLoaderRepository) this can still work, so if user hasn't</span>
-<span class="source-line-no">697</span><span id="line-697"> // forbidden it, just return the contextClassLoader.</span>
-<span class="source-line-no">698</span><span id="line-698"> if (!allowFlawedContext) {</span>
-<span class="source-line-no">699</span><span id="line-699"> throw new LogConfigurationException("Bad class loader hierarchy; LogFactoryImpl was loaded via" +</span>
-<span class="source-line-no">700</span><span id="line-700"> " a class loader that is not related to the current context" +</span>
-<span class="source-line-no">701</span><span id="line-701"> " class loader.");</span>
-<span class="source-line-no">702</span><span id="line-702"> }</span>
-<span class="source-line-no">703</span><span id="line-703"> if (isDiagnosticsEnabled()) {</span>
-<span class="source-line-no">704</span><span id="line-704"> logDiagnostic("[WARNING] the context class loader is not part of a" +</span>
-<span class="source-line-no">705</span><span id="line-705"> " parent-child relationship with the class loader that" +</span>
-<span class="source-line-no">706</span><span id="line-706"> " loaded LogFactoryImpl.");</span>
-<span class="source-line-no">707</span><span id="line-707"> }</span>
-<span class="source-line-no">708</span><span id="line-708"> // If contextClassLoader were null, getLowestClassLoader() would</span>
-<span class="source-line-no">709</span><span id="line-709"> // have returned thisClassLoader. The fact we are here means</span>
-<span class="source-line-no">710</span><span id="line-710"> // contextClassLoader is not null, so we can just return it.</span>
-<span class="source-line-no">711</span><span id="line-711"> return contextClassLoader;</span>
-<span class="source-line-no">712</span><span id="line-712"> }</span>
-<span class="source-line-no">713</span><span id="line-713"></span>
-<span class="source-line-no">714</span><span id="line-714"> if (baseClassLoader != contextClassLoader) {</span>
-<span class="source-line-no">715</span><span id="line-715"> // We really should just use the contextClassLoader as the starting</span>
-<span class="source-line-no">716</span><span id="line-716"> // point for scanning for log adapter classes. However it is expected</span>
-<span class="source-line-no">717</span><span id="line-717"> // that there are a number of broken systems out there which create</span>
-<span class="source-line-no">718</span><span id="line-718"> // custom class loaders but fail to set the context class loader so</span>
-<span class="source-line-no">719</span><span id="line-719"> // we handle those flawed systems anyway.</span>
-<span class="source-line-no">720</span><span id="line-720"> if (!allowFlawedContext) {</span>
-<span class="source-line-no">721</span><span id="line-721"> throw new LogConfigurationException(</span>
-<span class="source-line-no">722</span><span id="line-722"> "Bad class loader hierarchy; LogFactoryImpl was loaded via" +</span>
-<span class="source-line-no">723</span><span id="line-723"> " a class loader that is not related to the current context" +</span>
-<span class="source-line-no">724</span><span id="line-724"> " class loader.");</span>
-<span class="source-line-no">725</span><span id="line-725"> }</span>
-<span class="source-line-no">726</span><span id="line-726"> if (isDiagnosticsEnabled()) {</span>
-<span class="source-line-no">727</span><span id="line-727"> logDiagnostic(</span>
-<span class="source-line-no">728</span><span id="line-728"> "Warning: the context class loader is an ancestor of the" +</span>
-<span class="source-line-no">729</span><span id="line-729"> " class loader that loaded LogFactoryImpl; it should be" +</span>
-<span class="source-line-no">730</span><span id="line-730"> " the same or a descendant. The application using" +</span>
-<span class="source-line-no">731</span><span id="line-731"> " commons-logging should ensure the context class loader" +</span>
-<span class="source-line-no">732</span><span id="line-732"> " is used correctly.");</span>
-<span class="source-line-no">733</span><span id="line-733"> }</span>
-<span class="source-line-no">734</span><span id="line-734"> }</span>
-<span class="source-line-no">735</span><span id="line-735"></span>
-<span class="source-line-no">736</span><span id="line-736"> return baseClassLoader;</span>
-<span class="source-line-no">737</span><span id="line-737"> }</span>
-<span class="source-line-no">738</span><span id="line-738"></span>
-<span class="source-line-no">739</span><span id="line-739"> /**</span>
-<span class="source-line-no">740</span><span id="line-740"> * Gets the setting for the user-configurable behavior specified by key.</span>
-<span class="source-line-no">741</span><span id="line-741"> * If nothing has explicitly been set, then return dflt.</span>
-<span class="source-line-no">742</span><span id="line-742"> */</span>
-<span class="source-line-no">743</span><span id="line-743"> private boolean getBooleanConfiguration(final String key, final boolean dflt) {</span>
-<span class="source-line-no">744</span><span id="line-744"> final String val = getConfigurationValue(key);</span>
-<span class="source-line-no">745</span><span id="line-745"> if (val == null) {</span>
-<span class="source-line-no">746</span><span id="line-746"> return dflt;</span>
-<span class="source-line-no">747</span><span id="line-747"> }</span>
-<span class="source-line-no">748</span><span id="line-748"> return Boolean.parseBoolean(val);</span>
-<span class="source-line-no">749</span><span id="line-749"> }</span>
-<span class="source-line-no">750</span><span id="line-750"></span>
-<span class="source-line-no">751</span><span id="line-751"> /**</span>
-<span class="source-line-no">752</span><span id="line-752"> * Attempt to find an attribute (see method setAttribute) or a</span>
-<span class="source-line-no">753</span><span id="line-753"> * system property with the provided name and return its value.</span>
-<span class="source-line-no">754</span><span id="line-754"> * <p></span>
-<span class="source-line-no">755</span><span id="line-755"> * The attributes associated with this object are checked before</span>
-<span class="source-line-no">756</span><span id="line-756"> * system properties in case someone has explicitly called setAttribute,</span>
-<span class="source-line-no">757</span><span id="line-757"> * or a configuration property has been set in a commons-logging.properties</span>
-<span class="source-line-no">758</span><span id="line-758"> * file.</span>
-<span class="source-line-no">759</span><span id="line-759"> *</span>
-<span class="source-line-no">760</span><span id="line-760"> * @return the value associated with the property, or null.</span>
-<span class="source-line-no">761</span><span id="line-761"> */</span>
-<span class="source-line-no">762</span><span id="line-762"> private String getConfigurationValue(final String property) {</span>
-<span class="source-line-no">763</span><span id="line-763"> if (isDiagnosticsEnabled()) {</span>
-<span class="source-line-no">764</span><span id="line-764"> logDiagnostic("[ENV] Trying to get configuration for item " + property);</span>
-<span class="source-line-no">765</span><span id="line-765"> }</span>
-<span class="source-line-no">766</span><span id="line-766"></span>
-<span class="source-line-no">767</span><span id="line-767"> final Object valueObj = getAttribute(property);</span>
-<span class="source-line-no">768</span><span id="line-768"> if (valueObj != null) {</span>
-<span class="source-line-no">769</span><span id="line-769"> if (isDiagnosticsEnabled()) {</span>
-<span class="source-line-no">770</span><span id="line-770"> logDiagnostic("[ENV] Found LogFactory attribute [" + valueObj + "] for " + property);</span>
-<span class="source-line-no">771</span><span id="line-771"> }</span>
-<span class="source-line-no">772</span><span id="line-772"> return valueObj.toString();</span>
-<span class="source-line-no">773</span><span id="line-773"> }</span>
-<span class="source-line-no">774</span><span id="line-774"></span>
-<span class="source-line-no">775</span><span id="line-775"> if (isDiagnosticsEnabled()) {</span>
-<span class="source-line-no">776</span><span id="line-776"> logDiagnostic("[ENV] No LogFactory attribute found for " + property);</span>
-<span class="source-line-no">777</span><span id="line-777"> }</span>
-<span class="source-line-no">778</span><span id="line-778"></span>
-<span class="source-line-no">779</span><span id="line-779"> try {</span>
-<span class="source-line-no">780</span><span id="line-780"> // warning: minor security hole here, in that we potentially read a system</span>
-<span class="source-line-no">781</span><span id="line-781"> // property that the caller cannot, then output it in readable form as a</span>
-<span class="source-line-no">782</span><span id="line-782"> // diagnostic message. However it's only ever JCL-specific properties</span>
-<span class="source-line-no">783</span><span id="line-783"> // involved here, so the harm is truly trivial.</span>
-<span class="source-line-no">784</span><span id="line-784"> final String value = getSystemProperty(property, null);</span>
-<span class="source-line-no">785</span><span id="line-785"> if (value != null) {</span>
-<span class="source-line-no">786</span><span id="line-786"> if (isDiagnosticsEnabled()) {</span>
-<span class="source-line-no">787</span><span id="line-787"> logDiagnostic("[ENV] Found system property [" + value + "] for " + property);</span>
-<span class="source-line-no">788</span><span id="line-788"> }</span>
-<span class="source-line-no">789</span><span id="line-789"> return value;</span>
-<span class="source-line-no">790</span><span id="line-790"> }</span>
-<span class="source-line-no">791</span><span id="line-791"></span>
-<span class="source-line-no">792</span><span id="line-792"> if (isDiagnosticsEnabled()) {</span>
-<span class="source-line-no">793</span><span id="line-793"> logDiagnostic("[ENV] No system property found for property " + property);</span>
-<span class="source-line-no">794</span><span id="line-794"> }</span>
-<span class="source-line-no">795</span><span id="line-795"> } catch (final SecurityException e) {</span>
-<span class="source-line-no">796</span><span id="line-796"> if (isDiagnosticsEnabled()) {</span>
-<span class="source-line-no">797</span><span id="line-797"> logDiagnostic("[ENV] Security prevented reading system property " + property);</span>
-<span class="source-line-no">798</span><span id="line-798"> }</span>
-<span class="source-line-no">799</span><span id="line-799"> }</span>
-<span class="source-line-no">800</span><span id="line-800"></span>
-<span class="source-line-no">801</span><span id="line-801"> if (isDiagnosticsEnabled()) {</span>
-<span class="source-line-no">802</span><span id="line-802"> logDiagnostic("[ENV] No configuration defined for item " + property);</span>
-<span class="source-line-no">803</span><span id="line-803"> }</span>
-<span class="source-line-no">804</span><span id="line-804"></span>
-<span class="source-line-no">805</span><span id="line-805"> return null;</span>
-<span class="source-line-no">806</span><span id="line-806"> }</span>
-<span class="source-line-no">807</span><span id="line-807"></span>
-<span class="source-line-no">808</span><span id="line-808"> /**</span>
-<span class="source-line-no">809</span><span id="line-809"> * Convenience method to derive a name from the specified class and</span>
-<span class="source-line-no">810</span><span id="line-810"> * call {@code getInstance(String)} with it.</span>
-<span class="source-line-no">811</span><span id="line-811"> *</span>
-<span class="source-line-no">812</span><span id="line-812"> * @param clazz Class for which a suitable Log name will be derived</span>
-<span class="source-line-no">813</span><span id="line-813"> *</span>
-<span class="source-line-no">814</span><span id="line-814"> * @throws LogConfigurationException if a suitable {@code Log}</span>
-<span class="source-line-no">815</span><span id="line-815"> * instance cannot be returned</span>
-<span class="source-line-no">816</span><span id="line-816"> */</span>
-<span class="source-line-no">817</span><span id="line-817"> @Override</span>
-<span class="source-line-no">818</span><span id="line-818"> public Log getInstance(final Class<?> clazz) throws LogConfigurationException {</span>
-<span class="source-line-no">819</span><span id="line-819"> return getInstance(clazz.getName());</span>
-<span class="source-line-no">820</span><span id="line-820"> }</span>
-<span class="source-line-no">821</span><span id="line-821"></span>
-<span class="source-line-no">822</span><span id="line-822"> /**</span>
-<span class="source-line-no">823</span><span id="line-823"> * <p>Construct (if necessary) and return a {@code Log} instance,</span>
-<span class="source-line-no">824</span><span id="line-824"> * using the factory's current set of configuration attributes.</p></span>
-<span class="source-line-no">825</span><span id="line-825"> *</span>
-<span class="source-line-no">826</span><span id="line-826"> * <p><strong>NOTE</strong> - Depending upon the implementation of</span>
-<span class="source-line-no">827</span><span id="line-827"> * the {@code LogFactory} you are using, the {@code Log}</span>
-<span class="source-line-no">828</span><span id="line-828"> * instance you are returned may or may not be local to the current</span>
-<span class="source-line-no">829</span><span id="line-829"> * application, and may or may not be returned again on a subsequent</span>
-<span class="source-line-no">830</span><span id="line-830"> * call with the same name argument.</p></span>
-<span class="source-line-no">831</span><span id="line-831"> *</span>
-<span class="source-line-no">832</span><span id="line-832"> * @param name Logical name of the {@code Log} instance to be</span>
-<span class="source-line-no">833</span><span id="line-833"> * returned (the meaning of this name is only known to the underlying</span>
-<span class="source-line-no">834</span><span id="line-834"> * logging implementation that is being wrapped)</span>
-<span class="source-line-no">835</span><span id="line-835"> *</span>
-<span class="source-line-no">836</span><span id="line-836"> * @throws LogConfigurationException if a suitable {@code Log}</span>
-<span class="source-line-no">837</span><span id="line-837"> * instance cannot be returned</span>
-<span class="source-line-no">838</span><span id="line-838"> */</span>
-<span class="source-line-no">839</span><span id="line-839"> @Override</span>
-<span class="source-line-no">840</span><span id="line-840"> public Log getInstance(final String name) throws LogConfigurationException {</span>
-<span class="source-line-no">841</span><span id="line-841"> return instances.computeIfAbsent(name, this::newInstance);</span>
-<span class="source-line-no">842</span><span id="line-842"> }</span>
-<span class="source-line-no">843</span><span id="line-843"></span>
-<span class="source-line-no">844</span><span id="line-844"> /**</span>
-<span class="source-line-no">845</span><span id="line-845"> * Return the fully qualified Java class name of the {@link Log} implementation we will be using.</span>
-<span class="source-line-no">846</span><span id="line-846"> *</span>
-<span class="source-line-no">847</span><span id="line-847"> * @return the fully qualified Java class name of the {@link Log} implementation we will be using.</span>
-<span class="source-line-no">848</span><span id="line-848"> * @deprecated Never invoked by this class; subclasses should not assume it will be.</span>
-<span class="source-line-no">849</span><span id="line-849"> */</span>
-<span class="source-line-no">850</span><span id="line-850"> @Deprecated</span>
-<span class="source-line-no">851</span><span id="line-851"> protected String getLogClassName() {</span>
-<span class="source-line-no">852</span><span id="line-852"> if (logClassName == null) {</span>
-<span class="source-line-no">853</span><span id="line-853"> discoverLogImplementation(getClass().getName());</span>
-<span class="source-line-no">854</span><span id="line-854"> }</span>
-<span class="source-line-no">855</span><span id="line-855"></span>
-<span class="source-line-no">856</span><span id="line-856"> return logClassName;</span>
-<span class="source-line-no">857</span><span id="line-857"> }</span>
-<span class="source-line-no">858</span><span id="line-858"></span>
-<span class="source-line-no">859</span><span id="line-859"> /**</span>
-<span class="source-line-no">860</span><span id="line-860"> * <p></span>
-<span class="source-line-no">861</span><span id="line-861"> * Return the {@code Constructor} that can be called to instantiate new {@link org.apache.commons.logging.Log} instances.</span>
-<span class="source-line-no">862</span><span id="line-862"> * </p></span>
-<span class="source-line-no">863</span><span id="line-863"> *</span>
-<span class="source-line-no">864</span><span id="line-864"> * <p></span>
-<span class="source-line-no">865</span><span id="line-865"> * <strong>IMPLEMENTATION NOTE</strong> - Race conditions caused by calling this method from more than one thread are ignored, because the same</span>
-<span class="source-line-no">866</span><span id="line-866"> * {@code Constructor} instance will ultimately be derived in all circumstances.</span>
-<span class="source-line-no">867</span><span id="line-867"> * </p></span>
-<span class="source-line-no">868</span><span id="line-868"> *</span>
-<span class="source-line-no">869</span><span id="line-869"> * @return the {@code Constructor} that can be called to instantiate new {@link org.apache.commons.logging.Log} instances.</span>
-<span class="source-line-no">870</span><span id="line-870"> *</span>
-<span class="source-line-no">871</span><span id="line-871"> * @throws LogConfigurationException if a suitable constructor cannot be returned</span>
-<span class="source-line-no">872</span><span id="line-872"> *</span>
-<span class="source-line-no">873</span><span id="line-873"> * @deprecated Never invoked by this class; subclasses should not assume it will be.</span>
-<span class="source-line-no">874</span><span id="line-874"> */</span>
-<span class="source-line-no">875</span><span id="line-875"> @Deprecated</span>
-<span class="source-line-no">876</span><span id="line-876"> protected Constructor getLogConstructor()</span>
-<span class="source-line-no">877</span><span id="line-877"> throws LogConfigurationException {</span>
-<span class="source-line-no">878</span><span id="line-878"></span>
-<span class="source-line-no">879</span><span id="line-879"> // Return the previously identified Constructor (if any)</span>
-<span class="source-line-no">880</span><span id="line-880"> if (logConstructor == null) {</span>
-<span class="source-line-no">881</span><span id="line-881"> discoverLogImplementation(getClass().getName());</span>
-<span class="source-line-no">882</span><span id="line-882"> }</span>
-<span class="source-line-no">883</span><span id="line-883"></span>
-<span class="source-line-no">884</span><span id="line-884"> return logConstructor;</span>
-<span class="source-line-no">885</span><span id="line-885"> }</span>
-<span class="source-line-no">886</span><span id="line-886"></span>
-<span class="source-line-no">887</span><span id="line-887"> // ------------------------------------------------------ Private Methods</span>
-<span class="source-line-no">888</span><span id="line-888"></span>
-<span class="source-line-no">889</span><span id="line-889"> /**</span>
-<span class="source-line-no">890</span><span id="line-890"> * Given two related class loaders, return the one which is a child of</span>
-<span class="source-line-no">891</span><span id="line-891"> * the other.</span>
-<span class="source-line-no">892</span><span id="line-892"> * <p></span>
-<span class="source-line-no">893</span><span id="line-893"> * @param c1 is a class loader (including the null class loader)</span>
-<span class="source-line-no">894</span><span id="line-894"> * @param c2 is a class loader (including the null class loader)</span>
-<span class="source-line-no">895</span><span id="line-895"> *</span>
-<span class="source-line-no">896</span><span id="line-896"> * @return c1 if it has c2 as an ancestor, c2 if it has c1 as an ancestor,</span>
-<span class="source-line-no">897</span><span id="line-897"> * and null if neither is an ancestor of the other.</span>
-<span class="source-line-no">898</span><span id="line-898"> */</span>
-<span class="source-line-no">899</span><span id="line-899"> private ClassLoader getLowestClassLoader(final ClassLoader c1, final ClassLoader c2) {</span>
-<span class="source-line-no">900</span><span id="line-900"> // TODO: use AccessController when dealing with class loaders here</span>
-<span class="source-line-no">901</span><span id="line-901"></span>
-<span class="source-line-no">902</span><span id="line-902"> if (c1 == null) {</span>
-<span class="source-line-no">903</span><span id="line-903"> return c2;</span>
-<span class="source-line-no">904</span><span id="line-904"> }</span>
-<span class="source-line-no">905</span><span id="line-905"></span>
-<span class="source-line-no">906</span><span id="line-906"> if (c2 == null) {</span>
-<span class="source-line-no">907</span><span id="line-907"> return c1;</span>
-<span class="source-line-no">908</span><span id="line-908"> }</span>
-<span class="source-line-no">909</span><span id="line-909"></span>
-<span class="source-line-no">910</span><span id="line-910"> ClassLoader current;</span>
-<span class="source-line-no">911</span><span id="line-911"></span>
-<span class="source-line-no">912</span><span id="line-912"> // scan c1's ancestors to find c2</span>
-<span class="source-line-no">913</span><span id="line-913"> current = c1;</span>
-<span class="source-line-no">914</span><span id="line-914"> while (current != null) {</span>
-<span class="source-line-no">915</span><span id="line-915"> if (current == c2) {</span>
-<span class="source-line-no">916</span><span id="line-916"> return c1;</span>
-<span class="source-line-no">917</span><span id="line-917"> }</span>
-<span class="source-line-no">918</span><span id="line-918"> // current = current.getParent();</span>
-<span class="source-line-no">919</span><span id="line-919"> current = getParentClassLoader(current);</span>
-<span class="source-line-no">920</span><span id="line-920"> }</span>
-<span class="source-line-no">921</span><span id="line-921"></span>
-<span class="source-line-no">922</span><span id="line-922"> // scan c2's ancestors to find c1</span>
-<span class="source-line-no">923</span><span id="line-923"> current = c2;</span>
-<span class="source-line-no">924</span><span id="line-924"> while (current != null) {</span>
-<span class="source-line-no">925</span><span id="line-925"> if (current == c1) {</span>
-<span class="source-line-no">926</span><span id="line-926"> return c2;</span>
-<span class="source-line-no">927</span><span id="line-927"> }</span>
-<span class="source-line-no">928</span><span id="line-928"> // current = current.getParent();</span>
-<span class="source-line-no">929</span><span id="line-929"> current = getParentClassLoader(current);</span>
-<span class="source-line-no">930</span><span id="line-930"> }</span>
-<span class="source-line-no">931</span><span id="line-931"></span>
-<span class="source-line-no">932</span><span id="line-932"> return null;</span>
-<span class="source-line-no">933</span><span id="line-933"> }</span>
-<span class="source-line-no">934</span><span id="line-934"></span>
-<span class="source-line-no">935</span><span id="line-935"> /**</span>
-<span class="source-line-no">936</span><span id="line-936"> * Fetch the parent class loader of a specified class loader.</span>
-<span class="source-line-no">937</span><span id="line-937"> * <p></span>
-<span class="source-line-no">938</span><span id="line-938"> * If a SecurityException occurs, null is returned.</span>
-<span class="source-line-no">939</span><span id="line-939"> * <p></span>
-<span class="source-line-no">940</span><span id="line-940"> * Note that this method is non-static merely so logDiagnostic is available.</span>
-<span class="source-line-no">941</span><span id="line-941"> */</span>
-<span class="source-line-no">942</span><span id="line-942"> private ClassLoader getParentClassLoader(final ClassLoader cl) {</span>
-<span class="source-line-no">943</span><span id="line-943"> try {</span>
-<span class="source-line-no">944</span><span id="line-944"> return AccessController.doPrivileged((PrivilegedAction<ClassLoader>) () -> cl.getParent());</span>
-<span class="source-line-no">945</span><span id="line-945"> } catch (final SecurityException ex) {</span>
-<span class="source-line-no">946</span><span id="line-946"> logDiagnostic("[SECURITY] Unable to obtain parent class loader");</span>
-<span class="source-line-no">947</span><span id="line-947"> return null;</span>
-<span class="source-line-no">948</span><span id="line-948"> }</span>
-<span class="source-line-no">949</span><span id="line-949"></span>
-<span class="source-line-no">950</span><span id="line-950"> }</span>
-<span class="source-line-no">951</span><span id="line-951"></span>
-<span class="source-line-no">952</span><span id="line-952"> /**</span>
-<span class="source-line-no">953</span><span id="line-953"> * Generates an internal diagnostic logging of the discovery failure and</span>
-<span class="source-line-no">954</span><span id="line-954"> * then throws a {@code LogConfigurationException} that wraps</span>
-<span class="source-line-no">955</span><span id="line-955"> * the passed {@code Throwable}.</span>
-<span class="source-line-no">956</span><span id="line-956"> *</span>
-<span class="source-line-no">957</span><span id="line-957"> * @param logAdapterClassName is the class name of the Log implementation</span>
-<span class="source-line-no">958</span><span id="line-958"> * that could not be instantiated. Cannot be {@code null}.</span>
-<span class="source-line-no">959</span><span id="line-959"> * @param discoveryFlaw is the Throwable created by the class loader</span>
-<span class="source-line-no">960</span><span id="line-960"> *</span>
-<span class="source-line-no">961</span><span id="line-961"> * @throws LogConfigurationException ALWAYS</span>
-<span class="source-line-no">962</span><span id="line-962"> */</span>
-<span class="source-line-no">963</span><span id="line-963"> private void handleFlawedDiscovery(final String logAdapterClassName,</span>
-<span class="source-line-no">964</span><span id="line-964"> final Throwable discoveryFlaw) {</span>
-<span class="source-line-no">965</span><span id="line-965"></span>
-<span class="source-line-no">966</span><span id="line-966"> if (isDiagnosticsEnabled()) {</span>
-<span class="source-line-no">967</span><span id="line-967"> logDiagnostic("Could not instantiate Log '" +</span>
-<span class="source-line-no">968</span><span id="line-968"> logAdapterClassName + "' -- " +</span>
-<span class="source-line-no">969</span><span id="line-969"> discoveryFlaw.getClass().getName() + ": " +</span>
-<span class="source-line-no">970</span><span id="line-970"> discoveryFlaw.getLocalizedMessage());</span>
-<span class="source-line-no">971</span><span id="line-971"></span>
-<span class="source-line-no">972</span><span id="line-972"> if (discoveryFlaw instanceof InvocationTargetException ) {</span>
-<span class="source-line-no">973</span><span id="line-973"> // Ok, the lib is there but while trying to create a real underlying</span>
-<span class="source-line-no">974</span><span id="line-974"> // logger something failed in the underlying lib; display info about</span>
-<span class="source-line-no">975</span><span id="line-975"> // that if possible.</span>
-<span class="source-line-no">976</span><span id="line-976"> final InvocationTargetException ite = (InvocationTargetException) discoveryFlaw;</span>
-<span class="source-line-no">977</span><span id="line-977"> final Throwable cause = ite.getTargetException();</span>
-<span class="source-line-no">978</span><span id="line-978"> if (cause != null) {</span>
-<span class="source-line-no">979</span><span id="line-979"> logDiagnostic("... InvocationTargetException: " +</span>
-<span class="source-line-no">980</span><span id="line-980"> cause.getClass().getName() + ": " +</span>
-<span class="source-line-no">981</span><span id="line-981"> cause.getLocalizedMessage());</span>
-<span class="source-line-no">982</span><span id="line-982"></span>
-<span class="source-line-no">983</span><span id="line-983"> if (cause instanceof ExceptionInInitializerError) {</span>
-<span class="source-line-no">984</span><span id="line-984"> final ExceptionInInitializerError eiie = (ExceptionInInitializerError) cause;</span>
-<span class="source-line-no">985</span><span id="line-985"> final Throwable cause2 = eiie.getCause();</span>
-<span class="source-line-no">986</span><span id="line-986"> if (cause2 != null) {</span>
-<span class="source-line-no">987</span><span id="line-987"> final StringWriter sw = new StringWriter();</span>
-<span class="source-line-no">988</span><span id="line-988"> cause2.printStackTrace(new PrintWriter(sw, true));</span>
-<span class="source-line-no">989</span><span id="line-989"> logDiagnostic("... ExceptionInInitializerError: " + sw.toString());</span>
-<span class="source-line-no">990</span><span id="line-990"> }</span>
-<span class="source-line-no">991</span><span id="line-991"> }</span>
-<span class="source-line-no">992</span><span id="line-992"> }</span>
-<span class="source-line-no">993</span><span id="line-993"> }</span>
-<span class="source-line-no">994</span><span id="line-994"> }</span>
-<span class="source-line-no">995</span><span id="line-995"></span>
-<span class="source-line-no">996</span><span id="line-996"> if (!allowFlawedDiscovery) {</span>
-<span class="source-line-no">997</span><span id="line-997"> throw new LogConfigurationException(discoveryFlaw);</span>
-<span class="source-line-no">998</span><span id="line-998"> }</span>
-<span class="source-line-no">999</span><span id="line-999"> }</span>
-<span class="source-line-no">1000</span><span id="line-1000"></span>
-<span class="source-line-no">1001</span><span id="line-1001"> /**</span>
-<span class="source-line-no">1002</span><span id="line-1002"> * Report a problem loading the log adapter, then either return</span>
-<span class="source-line-no">1003</span><span id="line-1003"> * (if the situation is considered recoverable) or throw a</span>
-<span class="source-line-no">1004</span><span id="line-1004"> * LogConfigurationException.</span>
-<span class="source-line-no">1005</span><span id="line-1005"> * <p></span>
-<span class="source-line-no">1006</span><span id="line-1006"> * There are two possible reasons why we successfully loaded the</span>
-<span class="source-line-no">1007</span><span id="line-1007"> * specified log adapter class then failed to cast it to a Log object:</span>
-<span class="source-line-no">1008</span><span id="line-1008"> * <ol></span>
-<span class="source-line-no">1009</span><span id="line-1009"> * <li>the specific class just doesn't implement the Log interface</span>
-<span class="source-line-no">1010</span><span id="line-1010"> * (user screwed up), or</span>
-<span class="source-line-no">1011</span><span id="line-1011"> * <li> the specified class has bound to a Log class loaded by some other</span>
-<span class="source-line-no">1012</span><span id="line-1012"> * class loader; Log@ClassLoaderX cannot be cast to Log@ClassLoaderY.</span>
-<span class="source-line-no">1013</span><span id="line-1013"> * </ol></span>
-<span class="source-line-no">1014</span><span id="line-1014"> * <p></span>
-<span class="source-line-no">1015</span><span id="line-1015"> * Here we try to figure out which case has occurred so we can give the</span>
-<span class="source-line-no">1016</span><span id="line-1016"> * user some reasonable feedback.</span>
-<span class="source-line-no">1017</span><span id="line-1017"> *</span>
-<span class="source-line-no">1018</span><span id="line-1018"> * @param badClassLoader is the class loader we loaded the problem class from,</span>
-<span class="source-line-no">1019</span><span id="line-1019"> * ie it is equivalent to badClass.getClassLoader().</span>
-<span class="source-line-no">1020</span><span id="line-1020"> *</span>
-<span class="source-line-no">1021</span><span id="line-1021"> * @param badClass is a Class object with the desired name, but which</span>
-<span class="source-line-no">1022</span><span id="line-1022"> * does not implement Log correctly.</span>
-<span class="source-line-no">1023</span><span id="line-1023"> *</span>
-<span class="source-line-no">1024</span><span id="line-1024"> * @throws LogConfigurationException when the situation</span>
-<span class="source-line-no">1025</span><span id="line-1025"> * should not be recovered from.</span>
-<span class="source-line-no">1026</span><span id="line-1026"> */</span>
-<span class="source-line-no">1027</span><span id="line-1027"> private void handleFlawedHierarchy(final ClassLoader badClassLoader, final Class badClass)</span>
-<span class="source-line-no">1028</span><span id="line-1028"> throws LogConfigurationException {</span>
-<span class="source-line-no">1029</span><span id="line-1029"></span>
-<span class="source-line-no">1030</span><span id="line-1030"> boolean implementsLog = false;</span>
-<span class="source-line-no">1031</span><span id="line-1031"> final String logInterfaceName = Log.class.getName();</span>
-<span class="source-line-no">1032</span><span id="line-1032"> final Class[] interfaces = badClass.getInterfaces();</span>
-<span class="source-line-no">1033</span><span id="line-1033"> for (final Class element : interfaces) {</span>
-<span class="source-line-no">1034</span><span id="line-1034"> if (logInterfaceName.equals(element.getName())) {</span>
-<span class="source-line-no">1035</span><span id="line-1035"> implementsLog = true;</span>
-<span class="source-line-no">1036</span><span id="line-1036"> break;</span>
-<span class="source-line-no">1037</span><span id="line-1037"> }</span>
-<span class="source-line-no">1038</span><span id="line-1038"> }</span>
-<span class="source-line-no">1039</span><span id="line-1039"></span>
-<span class="source-line-no">1040</span><span id="line-1040"> if (implementsLog) {</span>
-<span class="source-line-no">1041</span><span id="line-1041"> // the class does implement an interface called Log, but</span>
-<span class="source-line-no">1042</span><span id="line-1042"> // it is in the wrong class loader</span>
-<span class="source-line-no">1043</span><span id="line-1043"> if (isDiagnosticsEnabled()) {</span>
-<span class="source-line-no">1044</span><span id="line-1044"> try {</span>
-<span class="source-line-no">1045</span><span id="line-1045"> final ClassLoader logInterfaceClassLoader = getClassLoader(Log.class);</span>
-<span class="source-line-no">1046</span><span id="line-1046"> logDiagnostic("Class '" + badClass.getName() + "' was found in class loader " +</span>
-<span class="source-line-no">1047</span><span id="line-1047"> objectId(badClassLoader) + ". It is bound to a Log interface which is not" +</span>
-<span class="source-line-no">1048</span><span id="line-1048"> " the one loaded from class loader " + objectId(logInterfaceClassLoader));</span>
-<span class="source-line-no">1049</span><span id="line-1049"> } catch (final Throwable t) {</span>
-<span class="source-line-no">1050</span><span id="line-1050"> handleThrowable(t); // may re-throw t</span>
-<span class="source-line-no">1051</span><span id="line-1051"> logDiagnostic("Error while trying to output diagnostics about" + " bad class '" + badClass + "'");</span>
-<span class="source-line-no">1052</span><span id="line-1052"> }</span>
-<span class="source-line-no">1053</span><span id="line-1053"> }</span>
-<span class="source-line-no">1054</span><span id="line-1054"></span>
-<span class="source-line-no">1055</span><span id="line-1055"> if (!allowFlawedHierarchy) {</span>
-<span class="source-line-no">1056</span><span id="line-1056"> final StringBuilder msg = new StringBuilder();</span>
-<span class="source-line-no">1057</span><span id="line-1057"> msg.append("Terminating logging for this context ");</span>
-<span class="source-line-no">1058</span><span id="line-1058"> msg.append("due to bad log hierarchy. ");</span>
-<span class="source-line-no">1059</span><span id="line-1059"> msg.append("You have more than one version of '");</span>
-<span class="source-line-no">1060</span><span id="line-1060"> msg.append(Log.class.getName());</span>
-<span class="source-line-no">1061</span><span id="line-1061"> msg.append("' visible.");</span>
-<span class="source-line-no">1062</span><span id="line-1062"> if (isDiagnosticsEnabled()) {</span>
-<span class="source-line-no">1063</span><span id="line-1063"> logDiagnostic(msg.toString());</span>
-<span class="source-line-no">1064</span><span id="line-1064"> }</span>
-<span class="source-line-no">1065</span><span id="line-1065"> throw new LogConfigurationException(msg.toString());</span>
-<span class="source-line-no">1066</span><span id="line-1066"> }</span>
-<span class="source-line-no">1067</span><span id="line-1067"></span>
-<span class="source-line-no">1068</span><span id="line-1068"> if (isDiagnosticsEnabled()) {</span>
-<span class="source-line-no">1069</span><span id="line-1069"> final StringBuilder msg = new StringBuilder();</span>
-<span class="source-line-no">1070</span><span id="line-1070"> msg.append("Warning: bad log hierarchy. ");</span>
-<span class="source-line-no">1071</span><span id="line-1071"> msg.append("You have more than one version of '");</span>
-<span class="source-line-no">1072</span><span id="line-1072"> msg.append(Log.class.getName());</span>
-<span class="source-line-no">1073</span><span id="line-1073"> msg.append("' visible.");</span>
-<span class="source-line-no">1074</span><span id="line-1074"> logDiagnostic(msg.toString());</span>
-<span class="source-line-no">1075</span><span id="line-1075"> }</span>
-<span class="source-line-no">1076</span><span id="line-1076"> } else {</span>
-<span class="source-line-no">1077</span><span id="line-1077"> // this is just a bad adapter class</span>
-<span class="source-line-no">1078</span><span id="line-1078"> if (!allowFlawedDiscovery) {</span>
-<span class="source-line-no">1079</span><span id="line-1079"> final StringBuilder msg = new StringBuilder();</span>
-<span class="source-line-no">1080</span><span id="line-1080"> msg.append("Terminating logging for this context. ");</span>
-<span class="source-line-no">1081</span><span id="line-1081"> msg.append("Log class '");</span>
-<span class="source-line-no">1082</span><span id="line-1082"> msg.append(badClass.getName());</span>
-<span class="source-line-no">1083</span><span id="line-1083"> msg.append("' does not implement the Log interface.");</span>
-<span class="source-line-no">1084</span><span id="line-1084"> if (isDiagnosticsEnabled()) {</span>
-<span class="source-line-no">1085</span><span id="line-1085"> logDiagnostic(msg.toString());</span>
-<span class="source-line-no">1086</span><span id="line-1086"> }</span>
-<span class="source-line-no">1087</span><span id="line-1087"></span>
-<span class="source-line-no">1088</span><span id="line-1088"> throw new LogConfigurationException(msg.toString());</span>
-<span class="source-line-no">1089</span><span id="line-1089"> }</span>
-<span class="source-line-no">1090</span><span id="line-1090"></span>
-<span class="source-line-no">1091</span><span id="line-1091"> if (isDiagnosticsEnabled()) {</span>
-<span class="source-line-no">1092</span><span id="line-1092"> final StringBuilder msg = new StringBuilder();</span>
-<span class="source-line-no">1093</span><span id="line-1093"> msg.append("[WARNING] Log class '");</span>
-<span class="source-line-no">1094</span><span id="line-1094"> msg.append(badClass.getName());</span>
-<span class="source-line-no">1095</span><span id="line-1095"> msg.append("' does not implement the Log interface.");</span>
-<span class="source-line-no">1096</span><span id="line-1096"> logDiagnostic(msg.toString());</span>
-<span class="source-line-no">1097</span><span id="line-1097"> }</span>
-<span class="source-line-no">1098</span><span id="line-1098"> }</span>
-<span class="source-line-no">1099</span><span id="line-1099"> }</span>
-<span class="source-line-no">1100</span><span id="line-1100"></span>
-<span class="source-line-no">1101</span><span id="line-1101"> /**</span>
-<span class="source-line-no">1102</span><span id="line-1102"> * Appends message if the given name is similar to the candidate.</span>
-<span class="source-line-no">1103</span><span id="line-1103"> * @param messageBuffer {@code StringBuffer} the message should be appended to,</span>
-<span class="source-line-no">1104</span><span id="line-1104"> * not null</span>
-<span class="source-line-no">1105</span><span id="line-1105"> * @param name the (trimmed) name to be test against the candidate, not null</span>
-<span class="source-line-no">1106</span><span id="line-1106"> * @param candidate the candidate name (not null)</span>
-<span class="source-line-no">1107</span><span id="line-1107"> */</span>
-<span class="source-line-no">1108</span><span id="line-1108"> private void informUponSimilarName(final StringBuilder messageBuffer, final String name,</span>
-<span class="source-line-no">1109</span><span id="line-1109"> final String candidate) {</span>
-<span class="source-line-no">1110</span><span id="line-1110"> if (name.equals(candidate)) {</span>
-<span class="source-line-no">1111</span><span id="line-1111"> // Don't suggest a name that is exactly the same as the one the</span>
-<span class="source-line-no">1112</span><span id="line-1112"> // user tried...</span>
-<span class="source-line-no">1113</span><span id="line-1113"> return;</span>
-<span class="source-line-no">1114</span><span id="line-1114"> }</span>
-<span class="source-line-no">1115</span><span id="line-1115"></span>
-<span class="source-line-no">1116</span><span id="line-1116"> // If the user provides a name that is in the right package, and gets</span>
-<span class="source-line-no">1117</span><span id="line-1117"> // the first 5 characters of the adapter class right (ignoring case),</span>
-<span class="source-line-no">1118</span><span id="line-1118"> // then suggest the candidate adapter class name.</span>
-<span class="source-line-no">1119</span><span id="line-1119"> if (name.regionMatches(true, 0, candidate, 0, PKG_LEN + 5)) {</span>
-<span class="source-line-no">1120</span><span id="line-1120"> messageBuffer.append(" Did you mean '");</span>
-<span class="source-line-no">1121</span><span id="line-1121"> messageBuffer.append(candidate);</span>
-<span class="source-line-no">1122</span><span id="line-1122"> messageBuffer.append("'?");</span>
-<span class="source-line-no">1123</span><span id="line-1123"> }</span>
-<span class="source-line-no">1124</span><span id="line-1124"> }</span>
-<span class="source-line-no">1125</span><span id="line-1125"></span>
-<span class="source-line-no">1126</span><span id="line-1126"> /**</span>
-<span class="source-line-no">1127</span><span id="line-1127"> * Initialize a number of variables that control the behavior of this</span>
-<span class="source-line-no">1128</span><span id="line-1128"> * class and that can be tweaked by the user. This is done when the first</span>
-<span class="source-line-no">1129</span><span id="line-1129"> * logger is created, not in the constructor of this class, because we</span>
-<span class="source-line-no">1130</span><span id="line-1130"> * need to give the user a chance to call method setAttribute in order to</span>
-<span class="source-line-no">1131</span><span id="line-1131"> * configure this object.</span>
-<span class="source-line-no">1132</span><span id="line-1132"> */</span>
-<span class="source-line-no">1133</span><span id="line-1133"> private void initConfiguration() {</span>
-<span class="source-line-no">1134</span><span id="line-1134"> allowFlawedContext = getBooleanConfiguration(ALLOW_FLAWED_CONTEXT_PROPERTY, true);</span>
-<span class="source-line-no">1135</span><span id="line-1135"> allowFlawedDiscovery = getBooleanConfiguration(ALLOW_FLAWED_DISCOVERY_PROPERTY, true);</span>
-<span class="source-line-no">1136</span><span id="line-1136"> allowFlawedHierarchy = getBooleanConfiguration(ALLOW_FLAWED_HIERARCHY_PROPERTY, true);</span>
-<span class="source-line-no">1137</span><span id="line-1137"> }</span>
-<span class="source-line-no">1138</span><span id="line-1138"></span>
-<span class="source-line-no">1139</span><span id="line-1139"> /**</span>
-<span class="source-line-no">1140</span><span id="line-1140"> * Calculate and cache a string that uniquely identifies this instance,</span>
-<span class="source-line-no">1141</span><span id="line-1141"> * including which class loader the object was loaded from.</span>
-<span class="source-line-no">1142</span><span id="line-1142"> * <p></span>
-<span class="source-line-no">1143</span><span id="line-1143"> * This string will later be prefixed to each "internal logging" message</span>
-<span class="source-line-no">1144</span><span id="line-1144"> * emitted, so that users can clearly see any unexpected behavior.</span>
-<span class="source-line-no">1145</span><span id="line-1145"> * <p></span>
-<span class="source-line-no">1146</span><span id="line-1146"> * Note that this method does not detect whether internal logging is</span>
-<span class="source-line-no">1147</span><span id="line-1147"> * enabled or not, nor where to output stuff if it is; that is all</span>
-<span class="source-line-no">1148</span><span id="line-1148"> * handled by the parent LogFactory class. This method just computes</span>
-<span class="source-line-no">1149</span><span id="line-1149"> * its own unique prefix for log messages.</span>
-<span class="source-line-no">1150</span><span id="line-1150"> */</span>
-<span class="source-line-no">1151</span><span id="line-1151"> private void initDiagnostics() {</span>
-<span class="source-line-no">1152</span><span id="line-1152"> // It would be nice to include an identifier of the context class loader</span>
-<span class="source-line-no">1153</span><span id="line-1153"> // that this LogFactoryImpl object is responsible for. However that</span>
-<span class="source-line-no">1154</span><span id="line-1154"> // isn't possible as that information isn't available. It is possible</span>
-<span class="source-line-no">1155</span><span id="line-1155"> // to figure this out by looking at the logging from LogFactory to</span>
-<span class="source-line-no">1156</span><span id="line-1156"> // see the context & impl ids from when this object was instantiated,</span>
-<span class="source-line-no">1157</span><span id="line-1157"> // in order to link the impl id output as this object's prefix back to</span>
-<span class="source-line-no">1158</span><span id="line-1158"> // the context it is intended to manage.</span>
-<span class="source-line-no">1159</span><span id="line-1159"> // Note that this prefix should be kept consistent with that</span>
-<span class="source-line-no">1160</span><span id="line-1160"> // in LogFactory.</span>
-<span class="source-line-no">1161</span><span id="line-1161"> final Class clazz = this.getClass();</span>
+<span class="source-line-no">679</span><span id="line-679"> */</span>
+<span class="source-line-no">680</span><span id="line-680"> private ClassLoader getBaseClassLoader() throws LogConfigurationException {</span>
+<span class="source-line-no">681</span><span id="line-681"> final ClassLoader thisClassLoader = getClassLoader(LogFactoryImpl.class);</span>
+<span class="source-line-no">682</span><span id="line-682"></span>
+<span class="source-line-no">683</span><span id="line-683"> if (!useTCCL) {</span>
+<span class="source-line-no">684</span><span id="line-684"> return thisClassLoader;</span>
+<span class="source-line-no">685</span><span id="line-685"> }</span>
+<span class="source-line-no">686</span><span id="line-686"></span>
+<span class="source-line-no">687</span><span id="line-687"> final ClassLoader contextClassLoader = getContextClassLoaderInternal();</span>
+<span class="source-line-no">688</span><span id="line-688"></span>
+<span class="source-line-no">689</span><span id="line-689"> final ClassLoader baseClassLoader = getLowestClassLoader(</span>
+<span class="source-line-no">690</span><span id="line-690"> contextClassLoader, thisClassLoader);</span>
+<span class="source-line-no">691</span><span id="line-691"></span>
+<span class="source-line-no">692</span><span id="line-692"> if (baseClassLoader == null) {</span>
+<span class="source-line-no">693</span><span id="line-693"> // The two class loaders are not part of a parent child relationship.</span>
+<span class="source-line-no">694</span><span id="line-694"> // In some classloading setups (e.g. JBoss with its</span>
+<span class="source-line-no">695</span><span id="line-695"> // UnifiedLoaderRepository) this can still work, so if user hasn't</span>
+<span class="source-line-no">696</span><span id="line-696"> // forbidden it, just return the contextClassLoader.</span>
+<span class="source-line-no">697</span><span id="line-697"> if (!allowFlawedContext) {</span>
+<span class="source-line-no">698</span><span id="line-698"> throw new LogConfigurationException("Bad class loader hierarchy; LogFactoryImpl was loaded via" +</span>
+<span class="source-line-no">699</span><span id="line-699"> " a class loader that is not related to the current context" +</span>
+<span class="source-line-no">700</span><span id="line-700"> " class loader.");</span>
+<span class="source-line-no">701</span><span id="line-701"> }</span>
+<span class="source-line-no">702</span><span id="line-702"> if (isDiagnosticsEnabled()) {</span>
+<span class="source-line-no">703</span><span id="line-703"> logDiagnostic("[WARNING] the context class loader is not part of a" +</span>
+<span class="source-line-no">704</span><span id="line-704"> " parent-child relationship with the class loader that" +</span>
+<span class="source-line-no">705</span><span id="line-705"> " loaded LogFactoryImpl.");</span>
+<span class="source-line-no">706</span><span id="line-706"> }</span>
+<span class="source-line-no">707</span><span id="line-707"> // If contextClassLoader were null, getLowestClassLoader() would</span>
+<span class="source-line-no">708</span><span id="line-708"> // have returned thisClassLoader. The fact we are here means</span>
+<span class="source-line-no">709</span><span id="line-709"> // contextClassLoader is not null, so we can just return it.</span>
+<span class="source-line-no">710</span><span id="line-710"> return contextClassLoader;</span>
+<span class="source-line-no">711</span><span id="line-711"> }</span>
+<span class="source-line-no">712</span><span id="line-712"></span>
+<span class="source-line-no">713</span><span id="line-713"> if (baseClassLoader != contextClassLoader) {</span>
+<span class="source-line-no">714</span><span id="line-714"> // We really should just use the contextClassLoader as the starting</span>
+<span class="source-line-no">715</span><span id="line-715"> // point for scanning for log adapter classes. However it is expected</span>
+<span class="source-line-no">716</span><span id="line-716"> // that there are a number of broken systems out there which create</span>
+<span class="source-line-no">717</span><span id="line-717"> // custom class loaders but fail to set the context class loader so</span>
+<span class="source-line-no">718</span><span id="line-718"> // we handle those flawed systems anyway.</span>
+<span class="source-line-no">719</span><span id="line-719"> if (!allowFlawedContext) {</span>
+<span class="source-line-no">720</span><span id="line-720"> throw new LogConfigurationException(</span>
+<span class="source-line-no">721</span><span id="line-721"> "Bad class loader hierarchy; LogFactoryImpl was loaded via" +</span>
+<span class="source-line-no">722</span><span id="line-722"> " a class loader that is not related to the current context" +</span>
+<span class="source-line-no">723</span><span id="line-723"> " class loader.");</span>
+<span class="source-line-no">724</span><span id="line-724"> }</span>
+<span class="source-line-no">725</span><span id="line-725"> if (isDiagnosticsEnabled()) {</span>
+<span class="source-line-no">726</span><span id="line-726"> logDiagnostic(</span>
+<span class="source-line-no">727</span><span id="line-727"> "Warning: the context class loader is an ancestor of the" +</span>
+<span class="source-line-no">728</span><span id="line-728"> " class loader that loaded LogFactoryImpl; it should be" +</span>
+<span class="source-line-no">729</span><span id="line-729"> " the same or a descendant. The application using" +</span>
+<span class="source-line-no">730</span><span id="line-730"> " commons-logging should ensure the context class loader" +</span>
+<span class="source-line-no">731</span><span id="line-731"> " is used correctly.");</span>
+<span class="source-line-no">732</span><span id="line-732"> }</span>
+<span class="source-line-no">733</span><span id="line-733"> }</span>
+<span class="source-line-no">734</span><span id="line-734"></span>
+<span class="source-line-no">735</span><span id="line-735"> return baseClassLoader;</span>
+<span class="source-line-no">736</span><span id="line-736"> }</span>
+<span class="source-line-no">737</span><span id="line-737"></span>
+<span class="source-line-no">738</span><span id="line-738"> /**</span>
+<span class="source-line-no">739</span><span id="line-739"> * Gets the setting for the user-configurable behavior specified by key.</span>
+<span class="source-line-no">740</span><span id="line-740"> * If nothing has explicitly been set, then return dflt.</span>
+<span class="source-line-no">741</span><span id="line-741"> */</span>
+<span class="source-line-no">742</span><span id="line-742"> private boolean getBooleanConfiguration(final String key, final boolean dflt) {</span>
+<span class="source-line-no">743</span><span id="line-743"> final String val = getConfigurationValue(key);</span>
+<span class="source-line-no">744</span><span id="line-744"> if (val == null) {</span>
+<span class="source-line-no">745</span><span id="line-745"> return dflt;</span>
+<span class="source-line-no">746</span><span id="line-746"> }</span>
+<span class="source-line-no">747</span><span id="line-747"> return Boolean.parseBoolean(val);</span>
+<span class="source-line-no">748</span><span id="line-748"> }</span>
+<span class="source-line-no">749</span><span id="line-749"></span>
+<span class="source-line-no">750</span><span id="line-750"> /**</span>
+<span class="source-line-no">751</span><span id="line-751"> * Attempt to find an attribute (see method setAttribute) or a</span>
+<span class="source-line-no">752</span><span id="line-752"> * system property with the provided name and return its value.</span>
+<span class="source-line-no">753</span><span id="line-753"> * <p></span>
+<span class="source-line-no">754</span><span id="line-754"> * The attributes associated with this object are checked before</span>
+<span class="source-line-no">755</span><span id="line-755"> * system properties in case someone has explicitly called setAttribute,</span>
+<span class="source-line-no">756</span><span id="line-756"> * or a configuration property has been set in a commons-logging.properties</span>
+<span class="source-line-no">757</span><span id="line-757"> * file.</span>
+<span class="source-line-no">758</span><span id="line-758"> *</span>
+<span class="source-line-no">759</span><span id="line-759"> * @return the value associated with the property, or null.</span>
+<span class="source-line-no">760</span><span id="line-760"> */</span>
+<span class="source-line-no">761</span><span id="line-761"> private String getConfigurationValue(final String property) {</span>
+<span class="source-line-no">762</span><span id="line-762"> if (isDiagnosticsEnabled()) {</span>
+<span class="source-line-no">763</span><span id="line-763"> logDiagnostic("[ENV] Trying to get configuration for item " + property);</span>
+<span class="source-line-no">764</span><span id="line-764"> }</span>
+<span class="source-line-no">765</span><span id="line-765"></span>
+<span class="source-line-no">766</span><span id="line-766"> final Object valueObj = getAttribute(property);</span>
+<span class="source-line-no">767</span><span id="line-767"> if (valueObj != null) {</span>
+<span class="source-line-no">768</span><span id="line-768"> if (isDiagnosticsEnabled()) {</span>
+<span class="source-line-no">769</span><span id="line-769"> logDiagnostic("[ENV] Found LogFactory attribute [" + valueObj + "] for " + property);</span>
+<span class="source-line-no">770</span><span id="line-770"> }</span>
+<span class="source-line-no">771</span><span id="line-771"> return valueObj.toString();</span>
+<span class="source-line-no">772</span><span id="line-772"> }</span>
+<span class="source-line-no">773</span><span id="line-773"></span>
+<span class="source-line-no">774</span><span id="line-774"> if (isDiagnosticsEnabled()) {</span>
+<span class="source-line-no">775</span><span id="line-775"> logDiagnostic("[ENV] No LogFactory attribute found for " + property);</span>
+<span class="source-line-no">776</span><span id="line-776"> }</span>
+<span class="source-line-no">777</span><span id="line-777"></span>
+<span class="source-line-no">778</span><span id="line-778"> try {</span>
+<span class="source-line-no">779</span><span id="line-779"> // warning: minor security hole here, in that we potentially read a system</span>
+<span class="source-line-no">780</span><span id="line-780"> // property that the caller cannot, then output it in readable form as a</span>
+<span class="source-line-no">781</span><span id="line-781"> // diagnostic message. However it's only ever JCL-specific properties</span>
+<span class="source-line-no">782</span><span id="line-782"> // involved here, so the harm is truly trivial.</span>
+<span class="source-line-no">783</span><span id="line-783"> final String value = getSystemProperty(property, null);</span>
+<span class="source-line-no">784</span><span id="line-784"> if (value != null) {</span>
+<span class="source-line-no">785</span><span id="line-785"> if (isDiagnosticsEnabled()) {</span>
+<span class="source-line-no">786</span><span id="line-786"> logDiagnostic("[ENV] Found system property [" + value + "] for " + property);</span>
+<span class="source-line-no">787</span><span id="line-787"> }</span>
+<span class="source-line-no">788</span><span id="line-788"> return value;</span>
+<span class="source-line-no">789</span><span id="line-789"> }</span>
+<span class="source-line-no">790</span><span id="line-790"></span>
+<span class="source-line-no">791</span><span id="line-791"> if (isDiagnosticsEnabled()) {</span>
+<span class="source-line-no">792</span><span id="line-792"> logDiagnostic("[ENV] No system property found for property " + property);</span>
+<span class="source-line-no">793</span><span id="line-793"> }</span>
+<span class="source-line-no">794</span><span id="line-794"> } catch (final SecurityException e) {</span>
+<span class="source-line-no">795</span><span id="line-795"> if (isDiagnosticsEnabled()) {</span>
+<span class="source-line-no">796</span><span id="line-796"> logDiagnostic("[ENV] Security prevented reading system property " + property);</span>
+<span class="source-line-no">797</span><span id="line-797"> }</span>
+<span class="source-line-no">798</span><span id="line-798"> }</span>
+<span class="source-line-no">799</span><span id="line-799"></span>
+<span class="source-line-no">800</span><span id="line-800"> if (isDiagnosticsEnabled()) {</span>
+<span class="source-line-no">801</span><span id="line-801"> logDiagnostic("[ENV] No configuration defined for item " + property);</span>
+<span class="source-line-no">802</span><span id="line-802"> }</span>
+<span class="source-line-no">803</span><span id="line-803"></span>
+<span class="source-line-no">804</span><span id="line-804"> return null;</span>
+<span class="source-line-no">805</span><span id="line-805"> }</span>
+<span class="source-line-no">806</span><span id="line-806"></span>
+<span class="source-line-no">807</span><span id="line-807"> /**</span>
+<span class="source-line-no">808</span><span id="line-808"> * Convenience method to derive a name from the specified class and</span>
+<span class="source-line-no">809</span><span id="line-809"> * call {@code getInstance(String)} with it.</span>
+<span class="source-line-no">810</span><span id="line-810"> *</span>
+<span class="source-line-no">811</span><span id="line-811"> * @param clazz Class for which a suitable Log name will be derived</span>
+<span class="source-line-no">812</span><span id="line-812"> *</span>
+<span class="source-line-no">813</span><span id="line-813"> * @throws LogConfigurationException if a suitable {@code Log}</span>
+<span class="source-line-no">814</span><span id="line-814"> * instance cannot be returned</span>
+<span class="source-line-no">815</span><span id="line-815"> */</span>
+<span class="source-line-no">816</span><span id="line-816"> @Override</span>
+<span class="source-line-no">817</span><span id="line-817"> public Log getInstance(final Class<?> clazz) throws LogConfigurationException {</span>
+<span class="source-line-no">818</span><span id="line-818"> return getInstance(clazz.getName());</span>
+<span class="source-line-no">819</span><span id="line-819"> }</span>
+<span class="source-line-no">820</span><span id="line-820"></span>
+<span class="source-line-no">821</span><span id="line-821"> /**</span>
+<span class="source-line-no">822</span><span id="line-822"> * <p>Construct (if necessary) and return a {@code Log} instance,</span>
+<span class="source-line-no">823</span><span id="line-823"> * using the factory's current set of configuration attributes.</p></span>
+<span class="source-line-no">824</span><span id="line-824"> *</span>
+<span class="source-line-no">825</span><span id="line-825"> * <p><strong>NOTE</strong> - Depending upon the implementation of</span>
+<span class="source-line-no">826</span><span id="line-826"> * the {@code LogFactory} you are using, the {@code Log}</span>
+<span class="source-line-no">827</span><span id="line-827"> * instance you are returned may or may not be local to the current</span>
+<span class="source-line-no">828</span><span id="line-828"> * application, and may or may not be returned again on a subsequent</span>
+<span class="source-line-no">829</span><span id="line-829"> * call with the same name argument.</p></span>
+<span class="source-line-no">830</span><span id="line-830"> *</span>
+<span class="source-line-no">831</span><span id="line-831"> * @param name Logical name of the {@code Log} instance to be</span>
+<span class="source-line-no">832</span><span id="line-832"> * returned (the meaning of this name is only known to the underlying</span>
+<span class="source-line-no">833</span><span id="line-833"> * logging implementation that is being wrapped)</span>
+<span class="source-line-no">834</span><span id="line-834"> *</span>
+<span class="source-line-no">835</span><span id="line-835"> * @throws LogConfigurationException if a suitable {@code Log}</span>
+<span class="source-line-no">836</span><span id="line-836"> * instance cannot be returned</span>
+<span class="source-line-no">837</span><span id="line-837"> */</span>
+<span class="source-line-no">838</span><span id="line-838"> @Override</span>
+<span class="source-line-no">839</span><span id="line-839"> public Log getInstance(final String name) throws LogConfigurationException {</span>
+<span class="source-line-no">840</span><span id="line-840"> return instances.computeIfAbsent(name, this::newInstance);</span>
+<span class="source-line-no">841</span><span id="line-841"> }</span>
+<span class="source-line-no">842</span><span id="line-842"></span>
+<span class="source-line-no">843</span><span id="line-843"> /**</span>
+<span class="source-line-no">844</span><span id="line-844"> * Gets the fully qualified Java class name of the {@link Log} implementation we will be using.</span>
+<span class="source-line-no">845</span><span id="line-845"> *</span>
+<span class="source-line-no">846</span><span id="line-846"> * @return the fully qualified Java class name of the {@link Log} implementation we will be using.</span>
+<span class="source-line-no">847</span><span id="line-847"> * @deprecated Never invoked by this class; subclasses should not assume it will be.</span>
+<span class="source-line-no">848</span><span id="line-848"> */</span>
+<span class="source-line-no">849</span><span id="line-849"> @Deprecated</span>
+<span class="source-line-no">850</span><span id="line-850"> protected String getLogClassName() {</span>
+<span class="source-line-no">851</span><span id="line-851"> if (logClassName == null) {</span>
+<span class="source-line-no">852</span><span id="line-852"> discoverLogImplementation(getClass().getName());</span>
+<span class="source-line-no">853</span><span id="line-853"> }</span>
+<span class="source-line-no">854</span><span id="line-854"></span>
+<span class="source-line-no">855</span><span id="line-855"> return logClassName;</span>
+<span class="source-line-no">856</span><span id="line-856"> }</span>
+<span class="source-line-no">857</span><span id="line-857"></span>
+<span class="source-line-no">858</span><span id="line-858"> /**</span>
+<span class="source-line-no">859</span><span id="line-859"> * <p></span>
+<span class="source-line-no">860</span><span id="line-860"> * Gets the {@code Constructor} that can be called to instantiate new {@link org.apache.commons.logging.Log} instances.</span>
+<span class="source-line-no">861</span><span id="line-861"> * </p></span>
+<span class="source-line-no">862</span><span id="line-862"> *</span>
+<span class="source-line-no">863</span><span id="line-863"> * <p></span>
+<span class="source-line-no">864</span><span id="line-864"> * <strong>IMPLEMENTATION NOTE</strong> - Race conditions caused by calling this method from more than one thread are ignored, because the same</span>
+<span class="source-line-no">865</span><span id="line-865"> * {@code Constructor} instance will ultimately be derived in all circumstances.</span>
+<span class="source-line-no">866</span><span id="line-866"> * </p></span>
+<span class="source-line-no">867</span><span id="line-867"> *</span>
+<span class="source-line-no">868</span><span id="line-868"> * @return the {@code Constructor} that can be called to instantiate new {@link org.apache.commons.logging.Log} instances.</span>
+<span class="source-line-no">869</span><span id="line-869"> *</span>
+<span class="source-line-no">870</span><span id="line-870"> * @throws LogConfigurationException if a suitable constructor cannot be returned</span>
+<span class="source-line-no">871</span><span id="line-871"> *</span>
+<span class="source-line-no">872</span><span id="line-872"> * @deprecated Never invoked by this class; subclasses should not assume it will be.</span>
+<span class="source-line-no">873</span><span id="line-873"> */</span>
+<span class="source-line-no">874</span><span id="line-874"> @Deprecated</span>
+<span class="source-line-no">875</span><span id="line-875"> protected Constructor<?> getLogConstructor()</span>
+<span class="source-line-no">876</span><span id="line-876"> throws LogConfigurationException {</span>
+<span class="source-line-no">877</span><span id="line-877"></span>
+<span class="source-line-no">878</span><span id="line-878"> // Return the previously identified Constructor (if any)</span>
+<span class="source-line-no">879</span><span id="line-879"> if (logConstructor == null) {</span>
+<span class="source-line-no">880</span><span id="line-880"> discoverLogImplementation(getClass().getName());</span>
+<span class="source-line-no">881</span><span id="line-881"> }</span>
+<span class="source-line-no">882</span><span id="line-882"></span>
+<span class="source-line-no">883</span><span id="line-883"> return logConstructor;</span>
+<span class="source-line-no">884</span><span id="line-884"> }</span>
+<span class="source-line-no">885</span><span id="line-885"></span>
+<span class="source-line-no">886</span><span id="line-886"> // ------------------------------------------------------ Private Methods</span>
+<span class="source-line-no">887</span><span id="line-887"></span>
+<span class="source-line-no">888</span><span id="line-888"> /**</span>
+<span class="source-line-no">889</span><span id="line-889"> * Given two related class loaders, return the one which is a child of</span>
+<span class="source-line-no">890</span><span id="line-890"> * the other.</span>
+<span class="source-line-no">891</span><span id="line-891"> * <p></span>
+<span class="source-line-no">892</span><span id="line-892"> * @param c1 is a class loader (including the null class loader)</span>
+<span class="source-line-no">893</span><span id="line-893"> * @param c2 is a class loader (including the null class loader)</span>
+<span class="source-line-no">894</span><span id="line-894"> *</span>
+<span class="source-line-no">895</span><span id="line-895"> * @return c1 if it has c2 as an ancestor, c2 if it has c1 as an ancestor,</span>
+<span class="source-line-no">896</span><span id="line-896"> * and null if neither is an ancestor of the other.</span>
+<span class="source-line-no">897</span><span id="line-897"> */</span>
+<span class="source-line-no">898</span><span id="line-898"> private ClassLoader getLowestClassLoader(final ClassLoader c1, final ClassLoader c2) {</span>
+<span class="source-line-no">899</span><span id="line-899"> // TODO: use AccessController when dealing with class loaders here</span>
+<span class="source-line-no">900</span><span id="line-900"></span>
+<span class="source-line-no">901</span><span id="line-901"> if (c1 == null) {</span>
+<span class="source-line-no">902</span><span id="line-902"> return c2;</span>
+<span class="source-line-no">903</span><span id="line-903"> }</span>
+<span class="source-line-no">904</span><span id="line-904"></span>
+<span class="source-line-no">905</span><span id="line-905"> if (c2 == null) {</span>
+<span class="source-line-no">906</span><span id="line-906"> return c1;</span>
+<span class="source-line-no">907</span><span id="line-907"> }</span>
+<span class="source-line-no">908</span><span id="line-908"></span>
+<span class="source-line-no">909</span><span id="line-909"> ClassLoader current;</span>
+<span class="source-line-no">910</span><span id="line-910"></span>
+<span class="source-line-no">911</span><span id="line-911"> // scan c1's ancestors to find c2</span>
+<span class="source-line-no">912</span><span id="line-912"> current = c1;</span>
+<span class="source-line-no">913</span><span id="line-913"> while (current != null) {</span>
+<span class="source-line-no">914</span><span id="line-914"> if (current == c2) {</span>
+<span class="source-line-no">915</span><span id="line-915"> return c1;</span>
+<span class="source-line-no">916</span><span id="line-916"> }</span>
+<span class="source-line-no">917</span><span id="line-917"> // current = current.getParent();</span>
+<span class="source-line-no">918</span><span id="line-918"> current = getParentClassLoader(current);</span>
+<span class="source-line-no">919</span><span id="line-919"> }</span>
+<span class="source-line-no">920</span><span id="line-920"></span>
+<span class="source-line-no">921</span><span id="line-921"> // scan c2's ancestors to find c1</span>
+<span class="source-line-no">922</span><span id="line-922"> current = c2;</span>
+<span class="source-line-no">923</span><span id="line-923"> while (current != null) {</span>
+<span class="source-line-no">924</span><span id="line-924"> if (current == c1) {</span>
+<span class="source-line-no">925</span><span id="line-925"> return c2;</span>
+<span class="source-line-no">926</span><span id="line-926"> }</span>
+<span class="source-line-no">927</span><span id="line-927"> // current = current.getParent();</span>
+<span class="source-line-no">928</span><span id="line-928"> current = getParentClassLoader(current);</span>
+<span class="source-line-no">929</span><span id="line-929"> }</span>
+<span class="source-line-no">930</span><span id="line-930"></span>
+<span class="source-line-no">931</span><span id="line-931"> return null;</span>
+<span class="source-line-no">932</span><span id="line-932"> }</span>
+<span class="source-line-no">933</span><span id="line-933"></span>
+<span class="source-line-no">934</span><span id="line-934"> /**</span>
+<span class="source-line-no">935</span><span id="line-935"> * Fetch the parent class loader of a specified class loader.</span>
+<span class="source-line-no">936</span><span id="line-936"> * <p></span>
+<span class="source-line-no">937</span><span id="line-937"> * If a SecurityException occurs, null is returned.</span>
+<span class="source-line-no">938</span><span id="line-938"> * <p></span>
+<span class="source-line-no">939</span><span id="line-939"> * Note that this method is non-static merely so logDiagnostic is available.</span>
+<span class="source-line-no">940</span><span id="line-940"> */</span>
+<span class="source-line-no">941</span><span id="line-941"> private ClassLoader getParentClassLoader(final ClassLoader cl) {</span>
+<span class="source-line-no">942</span><span id="line-942"> try {</span>
+<span class="source-line-no">943</span><span id="line-943"> return AccessController.doPrivileged((PrivilegedAction<ClassLoader>) () -> cl.getParent());</span>
+<span class="source-line-no">944</span><span id="line-944"> } catch (final SecurityException ex) {</span>
+<span class="source-line-no">945</span><span id="line-945"> logDiagnostic("[SECURITY] Unable to obtain parent class loader");</span>
+<span class="source-line-no">946</span><span id="line-946"> return null;</span>
+<span class="source-line-no">947</span><span id="line-947"> }</span>
+<span class="source-line-no">948</span><span id="line-948"></span>
[... 217 lines stripped ...]