AMQ-4746: Fixed ClassLoadingAwareObjectInputStream to load simple types first, 
using same logic as in Camel. This helps with AMQ clients in other runtimes 
such as Applet based or whatnot.


Project: http://git-wip-us.apache.org/repos/asf/activemq/repo
Commit: http://git-wip-us.apache.org/repos/asf/activemq/commit/b54a9422
Tree: http://git-wip-us.apache.org/repos/asf/activemq/tree/b54a9422
Diff: http://git-wip-us.apache.org/repos/asf/activemq/diff/b54a9422

Branch: refs/heads/activemq-5.9
Commit: b54a9422e166ebeae95e83ebc90adc1c7a750945
Parents: afc0f93
Author: Claus Ibsen <[email protected]>
Authored: Sat Nov 2 15:24:01 2013 +0100
Committer: Hadrian Zbarcea <[email protected]>
Committed: Wed Mar 12 08:30:11 2014 -0400

----------------------------------------------------------------------
 .../ClassLoadingAwareObjectInputStream.java     | 100 ++++++++++++++-----
 1 file changed, 75 insertions(+), 25 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/activemq/blob/b54a9422/activemq-client/src/main/java/org/apache/activemq/util/ClassLoadingAwareObjectInputStream.java
----------------------------------------------------------------------
diff --git 
a/activemq-client/src/main/java/org/apache/activemq/util/ClassLoadingAwareObjectInputStream.java
 
b/activemq-client/src/main/java/org/apache/activemq/util/ClassLoadingAwareObjectInputStream.java
index ccee17d..ca4d8a3 100644
--- 
a/activemq-client/src/main/java/org/apache/activemq/util/ClassLoadingAwareObjectInputStream.java
+++ 
b/activemq-client/src/main/java/org/apache/activemq/util/ClassLoadingAwareObjectInputStream.java
@@ -21,19 +21,16 @@ import java.io.InputStream;
 import java.io.ObjectInputStream;
 import java.io.ObjectStreamClass;
 import java.lang.reflect.Proxy;
-import java.util.HashMap;
 
-@SuppressWarnings("rawtypes")
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
 public class ClassLoadingAwareObjectInputStream extends ObjectInputStream {
 
+    private static final Logger LOG = 
LoggerFactory.getLogger(ClassLoadingAwareObjectInputStream.class);
     private static final ClassLoader FALLBACK_CLASS_LOADER =
         ClassLoadingAwareObjectInputStream.class.getClassLoader();
 
-    /**
-     * Maps primitive type names to corresponding class objects.
-     */
-    private static final HashMap<String, Class> primClasses = new 
HashMap<String, Class>(8, 1.0F);
-
     private final ClassLoader inLoader;
 
     public ClassLoadingAwareObjectInputStream(InputStream in) throws 
IOException {
@@ -72,31 +69,84 @@ public class ClassLoadingAwareObjectInputStream extends 
ObjectInputStream {
     }
 
     private Class<?> load(String className, ClassLoader... cl) throws 
ClassNotFoundException {
+        // check for simple types first
+        final Class<?> clazz = loadSimpleType(className);
+        if (clazz != null) {
+            LOG.trace("Loaded class: {} as simple type -> ", className, clazz);
+            return clazz;
+        }
+
+        // try the different class loaders
         for (ClassLoader loader : cl) {
+            LOG.trace("Attempting to load class: {} using classloader: {}", 
className, cl);
             try {
-                return Class.forName(className, false, loader);
+                Class<?> answer = Class.forName(className, false, loader);
+                if (LOG.isTraceEnabled()) {
+                    LOG.trace("Loaded class: {} using classloader: {} -> ", 
new Object[]{className, cl, answer});
+                }
+                return answer;
             } catch (ClassNotFoundException e) {
+                LOG.trace("Class not found: {} using classloader: {}", 
className, cl);
                 // ignore
             }
         }
-        // fallback
-        final Class<?> clazz = (Class<?>) primClasses.get(className);
-        if (clazz != null) {
-            return clazz;
-        } else {
-            return Class.forName(className, false, FALLBACK_CLASS_LOADER);
-        }
+
+        // and then the fallback class loader
+        return Class.forName(className, false, FALLBACK_CLASS_LOADER);
     }
 
-    static {
-        primClasses.put("boolean", boolean.class);
-        primClasses.put("byte", byte.class);
-        primClasses.put("char", char.class);
-        primClasses.put("short", short.class);
-        primClasses.put("int", int.class);
-        primClasses.put("long", long.class);
-        primClasses.put("float", float.class);
-        primClasses.put("double", double.class);
-        primClasses.put("void", void.class);
+    /**
+     * Load a simple type
+     *
+     * @param name the name of the class to load
+     * @return the class or <tt>null</tt> if it could not be loaded
+     */
+    public static Class<?> loadSimpleType(String name) {
+        // code from ObjectHelper.loadSimpleType in Apache Camel
+
+        // special for byte[] or Object[] as its common to use
+        if ("java.lang.byte[]".equals(name) || "byte[]".equals(name)) {
+            return byte[].class;
+        } else if ("java.lang.Byte[]".equals(name) || "Byte[]".equals(name)) {
+            return Byte[].class;
+        } else if ("java.lang.Object[]".equals(name) || 
"Object[]".equals(name)) {
+            return Object[].class;
+        } else if ("java.lang.String[]".equals(name) || 
"String[]".equals(name)) {
+            return String[].class;
+            // and these is common as well
+        } else if ("java.lang.String".equals(name) || "String".equals(name)) {
+            return String.class;
+        } else if ("java.lang.Boolean".equals(name) || "Boolean".equals(name)) 
{
+            return Boolean.class;
+        } else if ("boolean".equals(name)) {
+            return boolean.class;
+        } else if ("java.lang.Integer".equals(name) || "Integer".equals(name)) 
{
+            return Integer.class;
+        } else if ("int".equals(name)) {
+            return int.class;
+        } else if ("java.lang.Long".equals(name) || "Long".equals(name)) {
+            return Long.class;
+        } else if ("long".equals(name)) {
+            return long.class;
+        } else if ("java.lang.Short".equals(name) || "Short".equals(name)) {
+            return Short.class;
+        } else if ("short".equals(name)) {
+            return short.class;
+        } else if ("java.lang.Byte".equals(name) || "Byte".equals(name)) {
+            return Byte.class;
+        } else if ("byte".equals(name)) {
+            return byte.class;
+        } else if ("java.lang.Float".equals(name) || "Float".equals(name)) {
+            return Float.class;
+        } else if ("float".equals(name)) {
+            return float.class;
+        } else if ("java.lang.Double".equals(name) || "Double".equals(name)) {
+            return Double.class;
+        } else if ("double".equals(name)) {
+            return double.class;
+        }
+
+        return null;
     }
+
 }

Reply via email to