You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@activemq.apache.org by da...@apache.org on 2012/09/03 10:35:43 UTC

svn commit: r1380168 - in /activemq/trunk/activemq-core/src: main/java/org/apache/activemq/util/ test/java/org/apache/activemq/util/

Author: davsclaus
Date: Mon Sep  3 08:35:42 2012
New Revision: 1380168

URL: http://svn.apache.org/viewvc?rev=1380168&view=rev
Log:
AMQ-3797: Avoid using StringArrayEditor as property editor as it causes memory leak when undeploying app in a container such as Tomcat.

Added:
    activemq/trunk/activemq-core/src/main/java/org/apache/activemq/util/StringArrayConverter.java
      - copied, changed from r1380130, activemq/trunk/activemq-core/src/main/java/org/apache/activemq/util/StringArrayEditor.java
    activemq/trunk/activemq-core/src/test/java/org/apache/activemq/util/StringArrayConverterTest.java
      - copied, changed from r1380147, activemq/trunk/activemq-core/src/test/java/org/apache/activemq/util/StringArrayEditorTest.java
Removed:
    activemq/trunk/activemq-core/src/main/java/org/apache/activemq/util/StringArrayEditor.java
    activemq/trunk/activemq-core/src/test/java/org/apache/activemq/util/StringArrayEditorTest.java
Modified:
    activemq/trunk/activemq-core/src/main/java/org/apache/activemq/util/IntrospectionSupport.java

Modified: activemq/trunk/activemq-core/src/main/java/org/apache/activemq/util/IntrospectionSupport.java
URL: http://svn.apache.org/viewvc/activemq/trunk/activemq-core/src/main/java/org/apache/activemq/util/IntrospectionSupport.java?rev=1380168&r1=1380167&r2=1380168&view=diff
==============================================================================
--- activemq/trunk/activemq-core/src/main/java/org/apache/activemq/util/IntrospectionSupport.java (original)
+++ activemq/trunk/activemq-core/src/main/java/org/apache/activemq/util/IntrospectionSupport.java Mon Sep  3 08:35:42 2012
@@ -56,7 +56,6 @@ public final class IntrospectionSupport 
             String[] newSearchPath = list.toArray(new String[list.size()]);
             try {
                 PropertyEditorManager.setEditorSearchPath(newSearchPath);
-                PropertyEditorManager.registerEditor(String[].class, StringArrayEditor.class);
             } catch(java.security.AccessControlException ignore) {
                 // we might be in an applet...
             }
@@ -91,7 +90,7 @@ public final class IntrospectionSupport 
 
                 try {
 
-                    Object value = method.invoke(target, new Object[] {});
+                    Object value = method.invoke(target);
                     if (value == null) {
                         continue;
                     }
@@ -198,10 +197,10 @@ public final class IntrospectionSupport 
             // If the type is null or it matches the needed type, just use the
             // value directly
             if (value == null || value.getClass() == setter.getParameterTypes()[0]) {
-                setter.invoke(target, new Object[] {value});
+                setter.invoke(target, value);
             } else {
                 // We need to convert it
-                setter.invoke(target, new Object[] {convert(value, setter.getParameterTypes()[0])});
+                setter.invoke(target, convert(value, setter.getParameterTypes()[0]));
             }
             return true;
         } catch (Throwable ignore) {
@@ -210,6 +209,11 @@ public final class IntrospectionSupport 
     }
 
     private static Object convert(Object value, Class type) {
+        // special for String[] as we do not want to use a PropertyEditor for that
+        if (type.isAssignableFrom(String[].class)) {
+            return StringArrayConverter.convertToStringArray(value);
+        }
+
         PropertyEditor editor = PropertyEditorManager.findEditor(type);
         if (editor != null) {
             editor.setAsText(value.toString());
@@ -219,6 +223,12 @@ public final class IntrospectionSupport 
     }
 
     public static String convertToString(Object value, Class type) {
+        // special for String[] as we do not want to use a PropertyEditor for that
+        if (value != null && value.getClass().isAssignableFrom(String[].class)) {
+            String[] array = (String[]) value;
+            return StringArrayConverter.convertToString(array);
+        }
+
         PropertyEditor editor = PropertyEditorManager.findEditor(type);
         if (editor != null) {
             editor.setValue(value);
@@ -242,6 +252,11 @@ public final class IntrospectionSupport 
     }
 
     private static boolean isSettableType(Class clazz) {
+        // special for String[]
+        if (clazz.isAssignableFrom(String[].class)) {
+            return true;
+        }
+
         if (PropertyEditorManager.findEditor(clazz) != null) {
             return true;
         }

Copied: activemq/trunk/activemq-core/src/main/java/org/apache/activemq/util/StringArrayConverter.java (from r1380130, activemq/trunk/activemq-core/src/main/java/org/apache/activemq/util/StringArrayEditor.java)
URL: http://svn.apache.org/viewvc/activemq/trunk/activemq-core/src/main/java/org/apache/activemq/util/StringArrayConverter.java?p2=activemq/trunk/activemq-core/src/main/java/org/apache/activemq/util/StringArrayConverter.java&p1=activemq/trunk/activemq-core/src/main/java/org/apache/activemq/util/StringArrayEditor.java&r1=1380130&r2=1380168&rev=1380168&view=diff
==============================================================================
--- activemq/trunk/activemq-core/src/main/java/org/apache/activemq/util/StringArrayEditor.java (original)
+++ activemq/trunk/activemq-core/src/main/java/org/apache/activemq/util/StringArrayConverter.java Mon Sep  3 08:35:42 2012
@@ -16,44 +16,53 @@
  */
 package org.apache.activemq.util;
 
-import java.beans.PropertyEditorSupport;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.StringTokenizer;
 
+/**
+ * Class for converting to/from String[] to be used instead of a
+ * {@link java.beans.PropertyEditor} which otherwise causes
+ * memory leaks as the JDK {@link java.beans.PropertyEditorManager}
+ * is a static class and has strong references to classes, causing
+ * problems in hot-deployment environments.
+ */
+public class StringArrayConverter {
+
+    // TODO: Remove System.out
 
-public class StringArrayEditor extends PropertyEditorSupport {
+    public static String[] convertToStringArray(Object value) {
+        if (value == null) {
+            return null;
+        }
 
-    public void setAsText(String text) {
+        String text = value.toString();
         if (text == null || text.length() == 0) {
-            setValue(null);
-        } else {
-            StringTokenizer stok = new StringTokenizer(text, ",");
-            final List<String> list = new ArrayList<String>();
-
-            while (stok.hasMoreTokens()) {
-                list.add(stok.nextToken());
-            }
+            return null;
+        }
 
-            Object array = list.toArray(new String[list.size()]);
+        StringTokenizer stok = new StringTokenizer(text, ",");
+        final List<String> list = new ArrayList<String>();
 
-            setValue(array);
+        while (stok.hasMoreTokens()) {
+            list.add(stok.nextToken());
         }
+
+        String[] array = list.toArray(new String[list.size()]);
+        return array;
     }
 
-    public String getAsText() {
-        Object[] objects = (Object[]) getValue();
-        if (objects == null || objects.length == 0) {
+    public static String convertToString(String[] value) {
+        if (value == null || value.length == 0) {
             return null;
         }
 
-        StringBuffer result = new StringBuffer(String.valueOf(objects[0]));
-        for (int i = 1; i < objects.length; i++) {
-            result.append(",").append(objects[i]);
+        StringBuffer result = new StringBuffer(String.valueOf(value[0]));
+        for (int i = 1; i < value.length; i++) {
+            result.append(",").append(value[i]);
         }
 
         return result.toString();
-
     }
 
 }

Copied: activemq/trunk/activemq-core/src/test/java/org/apache/activemq/util/StringArrayConverterTest.java (from r1380147, activemq/trunk/activemq-core/src/test/java/org/apache/activemq/util/StringArrayEditorTest.java)
URL: http://svn.apache.org/viewvc/activemq/trunk/activemq-core/src/test/java/org/apache/activemq/util/StringArrayConverterTest.java?p2=activemq/trunk/activemq-core/src/test/java/org/apache/activemq/util/StringArrayConverterTest.java&p1=activemq/trunk/activemq-core/src/test/java/org/apache/activemq/util/StringArrayEditorTest.java&r1=1380147&r2=1380168&rev=1380168&view=diff
==============================================================================
--- activemq/trunk/activemq-core/src/test/java/org/apache/activemq/util/StringArrayEditorTest.java (original)
+++ activemq/trunk/activemq-core/src/test/java/org/apache/activemq/util/StringArrayConverterTest.java Mon Sep  3 08:35:42 2012
@@ -21,52 +21,35 @@ import junit.framework.TestCase;
 /**
  *
  */
-public class StringArrayEditorTest extends TestCase {
-
-    private StringArrayEditor editor = new StringArrayEditor();
+public class StringArrayConverterTest extends TestCase {
 
     public void testConvertToStringArray() throws Exception {
-        editor.setAsText(null);
-        assertEquals(null, editor.getValue());
-        editor.setAsText("");
-        assertEquals(null, editor.getValue());
+        assertEquals(null, StringArrayConverter.convertToStringArray(null));
+        assertEquals(null, StringArrayConverter.convertToStringArray(""));
 
-        editor.setAsText("foo");
-        String[] array = (String[]) editor.getValue();
+        String[] array = StringArrayConverter.convertToStringArray("foo");
         assertEquals(1, array.length);
         assertEquals("foo", array[0]);
 
-        editor.setAsText("foo,bar");
-        array = (String[]) editor.getValue();
+        array = StringArrayConverter.convertToStringArray("foo,bar");
         assertEquals(2, array.length);
         assertEquals("foo", array[0]);
         assertEquals("bar", array[1]);
 
-        editor.setAsText("foo,bar,baz");
-        array = (String[]) editor.getValue();
+        array = StringArrayConverter.convertToStringArray("foo,bar,baz");
+        assertEquals(3, array.length);
         assertEquals("foo", array[0]);
         assertEquals("bar", array[1]);
         assertEquals("baz", array[2]);
     }
 
     public void testConvertToString() throws Exception {
-        editor.setValue(null);
-        assertEquals(null, editor.getAsText());
-
-        editor.setValue(new String[]{});
-        assertEquals(null, editor.getAsText());
-
-        editor.setValue(new String[]{""});
-        assertEquals("", editor.getAsText());
-
-        editor.setValue(new String[]{"foo"});
-        assertEquals("foo", editor.getAsText());
-
-        editor.setValue(new String[]{"foo", "bar"});
-        assertEquals("foo,bar", editor.getAsText());
-
-        editor.setValue(new String[]{"foo", "bar", "baz"});
-        assertEquals("foo,bar,baz", editor.getAsText());
+        assertEquals(null, StringArrayConverter.convertToString(null));
+        assertEquals(null, StringArrayConverter.convertToString(new String[]{}));
+        assertEquals("", StringArrayConverter.convertToString(new String[]{""}));
+        assertEquals("foo", StringArrayConverter.convertToString(new String[]{"foo"}));
+        assertEquals("foo,bar", StringArrayConverter.convertToString(new String[]{"foo", "bar"}));
+        assertEquals("foo,bar,baz", StringArrayConverter.convertToString(new String[]{"foo", "bar", "baz"}));
     }
 
 }