Repository: logging-log4j2
Updated Branches:
  refs/heads/master d9cadbe9b -> 9422ca748


LOG4J-2030 - Inspect all known ClassLoaders to locate the service provider


Project: http://git-wip-us.apache.org/repos/asf/logging-log4j2/repo
Commit: http://git-wip-us.apache.org/repos/asf/logging-log4j2/commit/9422ca74
Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j2/tree/9422ca74
Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/9422ca74

Branch: refs/heads/master
Commit: 9422ca7489d545b92dda9dd357c1b057d7a2f217
Parents: d9cadbe
Author: Ralph Goers <[email protected]>
Authored: Tue Sep 5 23:27:46 2017 -0700
Committer: Ralph Goers <[email protected]>
Committed: Tue Sep 5 23:27:46 2017 -0700

----------------------------------------------------------------------
 .../org/apache/logging/log4j/spi/Provider.java  | 32 ++++++++++++++++++
 .../apache/logging/log4j/util/LoaderUtil.java   | 24 ++++++++++++++
 .../apache/logging/log4j/util/ProviderUtil.java |  6 ++--
 .../logging/log4j/util/ProviderUtilTest.java    | 34 ++++++++++++++++++++
 src/changes/changes.xml                         |  3 ++
 5 files changed, 97 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/9422ca74/log4j-api/src/main/java/org/apache/logging/log4j/spi/Provider.java
----------------------------------------------------------------------
diff --git a/log4j-api/src/main/java/org/apache/logging/log4j/spi/Provider.java 
b/log4j-api/src/main/java/org/apache/logging/log4j/spi/Provider.java
index 7882410..5808cf8 100644
--- a/log4j-api/src/main/java/org/apache/logging/log4j/spi/Provider.java
+++ b/log4j-api/src/main/java/org/apache/logging/log4j/spi/Provider.java
@@ -218,4 +218,36 @@ public class Provider {
         result.append("]");
         return result.toString();
     }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+
+        Provider provider = (Provider) o;
+
+        if (priority != null ? !priority.equals(provider.priority) : 
provider.priority != null) {
+            return false;
+        }
+        if (className != null ? !className.equals(provider.className) : 
provider.className != null) {
+            return false;
+        }
+        if (loggerContextFactoryClass != null ? 
!loggerContextFactoryClass.equals(provider.loggerContextFactoryClass) : 
provider.loggerContextFactoryClass != null) {
+            return false;
+        }
+        return versions != null ? versions.equals(provider.versions) : 
provider.versions == null;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = priority != null ? priority.hashCode() : 0;
+        result = 31 * result + (className != null ? className.hashCode() : 0);
+        result = 31 * result + (loggerContextFactoryClass != null ? 
loggerContextFactoryClass.hashCode() : 0);
+        result = 31 * result + (versions != null ? versions.hashCode() : 0);
+        return result;
+    }
 }

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/9422ca74/log4j-api/src/main/java/org/apache/logging/log4j/util/LoaderUtil.java
----------------------------------------------------------------------
diff --git 
a/log4j-api/src/main/java/org/apache/logging/log4j/util/LoaderUtil.java 
b/log4j-api/src/main/java/org/apache/logging/log4j/util/LoaderUtil.java
index 2f8a402..6f73044 100644
--- a/log4j-api/src/main/java/org/apache/logging/log4j/util/LoaderUtil.java
+++ b/log4j-api/src/main/java/org/apache/logging/log4j/util/LoaderUtil.java
@@ -21,9 +21,11 @@ import java.lang.reflect.InvocationTargetException;
 import java.net.URL;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
+import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Enumeration;
 import java.util.LinkedHashSet;
+import java.util.List;
 import java.util.Objects;
 
 /**
@@ -103,6 +105,28 @@ public final class LoaderUtil {
         }
     }
 
+    public static ClassLoader[] getClassLoaders() {
+        List<ClassLoader> classLoaders = new ArrayList<>();
+        ClassLoader tcl = getThreadContextClassLoader();
+        classLoaders.add(tcl);
+        ClassLoader current = LoaderUtil.class.getClassLoader();
+        if (current != tcl) {
+            classLoaders.add(current);
+            ClassLoader parent = current.getParent();
+            while (parent != null && !classLoaders.contains(parent)) {
+                classLoaders.add(parent);
+            }
+        }
+        ClassLoader parent = tcl;
+        while (parent != null && !classLoaders.contains(parent)) {
+            classLoaders.add(parent);
+        }
+        if (!classLoaders.contains(ClassLoader.getSystemClassLoader())) {
+            classLoaders.add(ClassLoader.getSystemClassLoader());
+        }
+        return classLoaders.toArray(new ClassLoader[classLoaders.size()]);
+    }
+
     /**
      * Determines if a named Class can be loaded or not.
      *

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/9422ca74/log4j-api/src/main/java/org/apache/logging/log4j/util/ProviderUtil.java
----------------------------------------------------------------------
diff --git 
a/log4j-api/src/main/java/org/apache/logging/log4j/util/ProviderUtil.java 
b/log4j-api/src/main/java/org/apache/logging/log4j/util/ProviderUtil.java
index 3c440a9..75414f4 100644
--- a/log4j-api/src/main/java/org/apache/logging/log4j/util/ProviderUtil.java
+++ b/log4j-api/src/main/java/org/apache/logging/log4j/util/ProviderUtil.java
@@ -63,7 +63,9 @@ public final class ProviderUtil {
     private static volatile ProviderUtil instance;
 
     private ProviderUtil() {
-        loadProviders(findClassLoader());
+        for (ClassLoader classLoader : LoaderUtil.getClassLoaders()) {
+            loadProviders(classLoader);
+        }
         for (final LoaderUtil.UrlResource resource : 
LoaderUtil.findUrlResources(PROVIDER_RESOURCE)) {
             loadProvider(resource.getUrl(), resource.getClassLoader());
         }
@@ -97,7 +99,7 @@ public final class ProviderUtil {
     protected static void loadProviders(final ClassLoader cl) {
         final ServiceLoader<Provider> serviceLoader = 
ServiceLoader.load(Provider.class, cl);
         for (final Provider provider : serviceLoader) {
-            if (validVersion(provider.getVersions())) {
+            if (validVersion(provider.getVersions()) && 
!PROVIDERS.contains(provider)) {
                 PROVIDERS.add(provider);
             }
         }

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/9422ca74/log4j-api/src/test/java/org/apache/logging/log4j/util/ProviderUtilTest.java
----------------------------------------------------------------------
diff --git 
a/log4j-api/src/test/java/org/apache/logging/log4j/util/ProviderUtilTest.java 
b/log4j-api/src/test/java/org/apache/logging/log4j/util/ProviderUtilTest.java
new file mode 100644
index 0000000..ec8887b
--- /dev/null
+++ 
b/log4j-api/src/test/java/org/apache/logging/log4j/util/ProviderUtilTest.java
@@ -0,0 +1,34 @@
+package org.apache.logging.log4j.util;
+
+import java.io.File;
+import java.net.URL;
+import java.net.URLClassLoader;
+
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.TestLoggerContext;
+import org.apache.logging.log4j.spi.LoggerContext;
+import org.junit.Test;
+
+import static org.junit.Assert.assertTrue;
+
+public class ProviderUtilTest {
+
+    @Test
+    public void complexTest() throws Exception {
+        File file = new File("target/classes");
+        ClassLoader classLoader = new URLClassLoader(new URL[] 
{file.toURI().toURL()});
+        Worker worker = new Worker();
+        worker.setContextClassLoader(classLoader);
+        worker.start();
+        worker.join();
+        assertTrue("Incorrect LoggerContext", worker.context instanceof 
TestLoggerContext);
+    }
+
+    private class Worker extends Thread {
+        LoggerContext context = null;
+
+        public void run() {
+            context = LogManager.getContext(false);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/9422ca74/src/changes/changes.xml
----------------------------------------------------------------------
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index 17e9594..773663e 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -31,6 +31,9 @@
          - "remove" - Removed
     -->
     <release version="2.9.1" date="2017-MM-DD" description="GA Release 2.9.1">
+      <action issue="LOG4J2-2030" dev="rgoers" type="fix">
+        Inspect all known ClassLoaders to locate the service provider"
+      </action>
       <action issue="LOG4J2-2028" dev="rgoers" type="fix" due-to="Jason Tedor">
         Java 9 StackLocator was not properly skipping the initial stack frames.
       </action>

Reply via email to