logging-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From grobme...@apache.org
Subject svn commit: r1332275 - in /logging/log4j/trunk: src/main/java/org/apache/log4j/MDC.java tests/src/java/org/apache/log4j/MDCTestCase.java
Date Mon, 30 Apr 2012 16:14:03 GMT
Author: grobmeier
Date: Mon Apr 30 16:14:02 2012
New Revision: 1332275

URL: http://svn.apache.org/viewvc?rev=1332275&view=rev
Log:
applied one more mdc fix from Maarten Bosteels. Thanks!

Added:
    logging/log4j/trunk/tests/src/java/org/apache/log4j/MDCTestCase.java   (with props)
Modified:
    logging/log4j/trunk/src/main/java/org/apache/log4j/MDC.java

Modified: logging/log4j/trunk/src/main/java/org/apache/log4j/MDC.java
URL: http://svn.apache.org/viewvc/logging/log4j/trunk/src/main/java/org/apache/log4j/MDC.java?rev=1332275&r1=1332274&r2=1332275&view=diff
==============================================================================
--- logging/log4j/trunk/src/main/java/org/apache/log4j/MDC.java (original)
+++ logging/log4j/trunk/src/main/java/org/apache/log4j/MDC.java Mon Apr 30 16:14:02 2012
@@ -41,7 +41,8 @@ import org.apache.log4j.helpers.ThreadLo
    
    @since 1.2
 
-   @author Ceki Gülcü */
+   @author Ceki Gülcü 
+*/
 public class MDC {
   
   final static MDC mdc = new MDC();
@@ -53,7 +54,7 @@ public class MDC {
   Object tlm;
 
   private Method removeMethod;
-    
+
   private
   MDC() {
     java1 = Loader.isJava1();
@@ -170,6 +171,10 @@ public class MDC {
       Hashtable ht = (Hashtable) ((ThreadLocalMap)tlm).get();
       if(ht != null) {
         ht.remove(key);
+        // clean up if this was the last key
+        if (ht.isEmpty()) {
+          clear0();
+        }
       } 
     }
   }

Added: logging/log4j/trunk/tests/src/java/org/apache/log4j/MDCTestCase.java
URL: http://svn.apache.org/viewvc/logging/log4j/trunk/tests/src/java/org/apache/log4j/MDCTestCase.java?rev=1332275&view=auto
==============================================================================
--- logging/log4j/trunk/tests/src/java/org/apache/log4j/MDCTestCase.java (added)
+++ logging/log4j/trunk/tests/src/java/org/apache/log4j/MDCTestCase.java Mon Apr 30 16:14:02
2012
@@ -0,0 +1,98 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.log4j;
+
+import java.lang.ref.Reference;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import junit.framework.TestCase;
+
+/**
+ * Test for MDC
+ * 
+ *  @author Maarten Bosteels
+ */
+public class MDCTestCase extends TestCase {
+
+  public void setUp() {
+    MDC.clear();
+  }
+
+  public void tearDown() {
+    MDC.clear();
+  }
+
+  public void testPut() throws Exception {
+    MDC.put("key", "some value");
+    assertEquals("some value", MDC.get("key"));
+    assertEquals(1, MDC.getContext().size());
+  }
+  
+  public void testRemoveLastKey() throws Exception {
+    MDC.put("key", "some value");
+
+    MDC.remove("key");
+    checkThreadLocalsForLeaks();
+  }
+
+  private void checkThreadLocalsForLeaks() throws Exception {
+
+      // this code is heavily based on code in org.apache.catalina.loader.WebappClassLoader
+
+      // Make the fields in the Thread class that store ThreadLocals accessible    
+      Field threadLocalsField = Thread.class.getDeclaredField("threadLocals");
+      threadLocalsField.setAccessible(true);
+      Field inheritableThreadLocalsField = Thread.class.getDeclaredField("inheritableThreadLocals");
+      inheritableThreadLocalsField.setAccessible(true);
+      // Make the underlying array of ThreadLoad.ThreadLocalMap.Entry objects accessible
+      Class tlmClass = Class.forName("java.lang.ThreadLocal$ThreadLocalMap");
+      Field tableField = tlmClass.getDeclaredField("table");
+      tableField.setAccessible(true);
+
+      Thread thread = Thread.currentThread();
+
+      Object threadLocalMap;
+      threadLocalMap = threadLocalsField.get(thread);
+      // Check the first map
+      checkThreadLocalMapForLeaks(threadLocalMap, tableField);
+      // Check the second map
+      threadLocalMap = inheritableThreadLocalsField.get(thread);
+      checkThreadLocalMapForLeaks(threadLocalMap, tableField);
+
+  }
+
+  private void checkThreadLocalMapForLeaks(Object map, Field internalTableField) 
+          throws IllegalAccessException, NoSuchFieldException {
+    if (map != null) {
+      Object[] table = (Object[]) internalTableField.get(map);
+      if (table != null) {
+        for (int j =0; j < table.length; j++) {
+          if (table[j] != null) {
+
+            // Check the key
+            Object key = ((Reference) table[j]).get();
+            String keyClassName = key.getClass().getName();
+
+            if (key.getClass() == org.apache.log4j.helpers.ThreadLocalMap.class) {
+              fail("Found a ThreadLocal with key of type [" + keyClassName + "]");
+            }
+          }
+        }
+      }
+    }
+  }
+}

Propchange: logging/log4j/trunk/tests/src/java/org/apache/log4j/MDCTestCase.java
------------------------------------------------------------------------------
    svn:eol-style = native



Mime
View raw message