LOG4J2-1176 use weak reference to classloader in Provider to prevent
memory leaks when web app is unloaded

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

Branch: refs/heads/LOG4J-1181
Commit: 60dd22656e106d8476cca70c17475917bb8cf744
Parents: 83c2247
Author: rpopma <rpo...@apache.org>
Authored: Sun Nov 8 15:38:19 2015 +0900
Committer: rpopma <rpo...@apache.org>
Committed: Sun Nov 8 15:38:19 2015 +0900

----------------------------------------------------------------------
 .../org/apache/logging/log4j/spi/Provider.java  | 40 ++++++++++++++++++--
 1 file changed, 36 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/60dd2265/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 cd54d43..f5c9f48 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
@@ -16,6 +16,7 @@
  */
 package org.apache.logging.log4j.spi;
 
+import java.lang.ref.WeakReference;
 import java.net.URL;
 import java.util.Properties;
 
@@ -48,11 +49,11 @@ public class Provider {
     private final String className;
     private final String threadContextMap;
     private final URL url;
-    private final ClassLoader classLoader;
+    private final WeakReference<ClassLoader> classLoader;
 
     public Provider(final Properties props, final URL url, final ClassLoader 
classLoader) {
         this.url = url;
-        this.classLoader = classLoader;
+        this.classLoader = new WeakReference<ClassLoader>(classLoader);
         final String weight = props.getProperty(FACTORY_PRIORITY);
         priority = weight == null ? DEFAULT_PRIORITY : Integer.valueOf(weight);
         className = props.getProperty(LOGGER_CONTEXT_FACTORY);
@@ -87,8 +88,12 @@ public class Provider {
         if (className == null) {
             return null;
         }
+        ClassLoader loader = classLoader.get();
+        if (loader == null) {
+            return null;
+        }
         try {
-            final Class<?> clazz = classLoader.loadClass(className);
+            final Class<?> clazz = loader.loadClass(className);
             if (LoggerContextFactory.class.isAssignableFrom(clazz)) {
                 return clazz.asSubclass(LoggerContextFactory.class);
             }
@@ -116,8 +121,12 @@ public class Provider {
         if (threadContextMap == null) {
             return null;
         }
+        ClassLoader loader = classLoader.get();
+        if (loader == null) {
+            return null;
+        }
         try {
-            final Class<?> clazz = classLoader.loadClass(threadContextMap);
+            final Class<?> clazz = loader.loadClass(threadContextMap);
             if (ThreadContextMap.class.isAssignableFrom(clazz)) {
                 return clazz.asSubclass(ThreadContextMap.class);
             }
@@ -135,4 +144,27 @@ public class Provider {
     public URL getUrl() {
         return url;
     }
+    
+    @Override
+    public String toString() {
+        String result = "Provider[";
+        if (priority != DEFAULT_PRIORITY) {
+            result += "priority=" + priority + ", ";
+        }
+        if (threadContextMap != null) {
+            result += "threadContextMap=" + threadContextMap + ", ";
+        }
+        if (className != null) {
+            result += "className=" + className + ", ";
+        }
+        result += "url=" + url;
+        final ClassLoader loader = classLoader.get();
+        if (loader == null) {
+            result += ", classLoader=null(not reachable)";
+        } else {
+            result += ", classLoader=" + loader;
+        }
+        result += "]";
+        return result;
+    }
 }

Reply via email to