activemq-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From tab...@apache.org
Subject svn commit: r1195708 - in /activemq/trunk/activemq-core/src: main/java/org/apache/activemq/util/ClassLoadingAwareObjectInputStream.java test/java/org/apache/activemq/bugs/AMQ3537Test.java
Date Mon, 31 Oct 2011 22:34:17 GMT
Author: tabish
Date: Mon Oct 31 22:34:16 2011
New Revision: 1195708

URL: http://svn.apache.org/viewvc?rev=1195708&view=rev
Log:
Fix for: https://issues.apache.org/jira/browse/AMQ-3537

Added:
    activemq/trunk/activemq-core/src/test/java/org/apache/activemq/bugs/AMQ3537Test.java 
 (with props)
Modified:
    activemq/trunk/activemq-core/src/main/java/org/apache/activemq/util/ClassLoadingAwareObjectInputStream.java

Modified: activemq/trunk/activemq-core/src/main/java/org/apache/activemq/util/ClassLoadingAwareObjectInputStream.java
URL: http://svn.apache.org/viewvc/activemq/trunk/activemq-core/src/main/java/org/apache/activemq/util/ClassLoadingAwareObjectInputStream.java?rev=1195708&r1=1195707&r2=1195708&view=diff
==============================================================================
--- activemq/trunk/activemq-core/src/main/java/org/apache/activemq/util/ClassLoadingAwareObjectInputStream.java
(original)
+++ activemq/trunk/activemq-core/src/main/java/org/apache/activemq/util/ClassLoadingAwareObjectInputStream.java
Mon Oct 31 22:34:16 2011
@@ -23,21 +23,27 @@ import java.io.ObjectStreamClass;
 import java.lang.reflect.Proxy;
 import java.util.HashMap;
 
+@SuppressWarnings("rawtypes")
 public class ClassLoadingAwareObjectInputStream extends ObjectInputStream {
 
-    private static final ClassLoader FALLBACK_CLASS_LOADER = ClassLoadingAwareObjectInputStream.class.getClassLoader();
-    /** <p>Maps primitive type names to corresponding class objects.</p> */
+    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);
+
     public ClassLoadingAwareObjectInputStream(InputStream in) throws IOException {
         super(in);
     }
 
-    protected Class resolveClass(ObjectStreamClass classDesc) throws IOException, ClassNotFoundException
{
+    protected Class<?> resolveClass(ObjectStreamClass classDesc) throws IOException,
ClassNotFoundException {
         ClassLoader cl = Thread.currentThread().getContextClassLoader();
         return load(classDesc.getName(), cl);
     }
 
-    protected Class resolveProxyClass(String[] interfaces) throws IOException, ClassNotFoundException
{
+    protected Class<?> resolveProxyClass(String[] interfaces) throws IOException, ClassNotFoundException
{
         ClassLoader cl = Thread.currentThread().getContextClassLoader();
         Class[] cinterfaces = new Class[interfaces.length];
         for (int i = 0; i < interfaces.length; i++) {
@@ -45,18 +51,22 @@ public class ClassLoadingAwareObjectInpu
         }
 
         try {
-            return Proxy.getProxyClass(cinterfaces[0].getClassLoader(), cinterfaces);
+            return Proxy.getProxyClass(cl, cinterfaces);
         } catch (IllegalArgumentException e) {
+            try {
+                return Proxy.getProxyClass(FALLBACK_CLASS_LOADER, cinterfaces);
+            } catch (IllegalArgumentException e1) {
+            }
+
             throw new ClassNotFoundException(null, e);
         }
     }
 
-    private Class load(String className, ClassLoader cl)
-            throws ClassNotFoundException {
+    private Class<?> load(String className, ClassLoader cl) throws ClassNotFoundException
{
         try {
             return Class.forName(className, false, cl);
         } catch (ClassNotFoundException e) {
-            final Class clazz = (Class) primClasses.get(className);
+            final Class<?> clazz = (Class<?>) primClasses.get(className);
             if (clazz != null) {
                 return clazz;
             } else {
@@ -64,9 +74,7 @@ public class ClassLoadingAwareObjectInpu
             }
         }
     }
-    
-    
-    
+
     static {
         primClasses.put("boolean", boolean.class);
         primClasses.put("byte", byte.class);
@@ -78,5 +86,4 @@ public class ClassLoadingAwareObjectInpu
         primClasses.put("double", double.class);
         primClasses.put("void", void.class);
     }
-
 }

Added: activemq/trunk/activemq-core/src/test/java/org/apache/activemq/bugs/AMQ3537Test.java
URL: http://svn.apache.org/viewvc/activemq/trunk/activemq-core/src/test/java/org/apache/activemq/bugs/AMQ3537Test.java?rev=1195708&view=auto
==============================================================================
--- activemq/trunk/activemq-core/src/test/java/org/apache/activemq/bugs/AMQ3537Test.java (added)
+++ activemq/trunk/activemq-core/src/test/java/org/apache/activemq/bugs/AMQ3537Test.java Mon
Oct 31 22:34:16 2011
@@ -0,0 +1,102 @@
+/**
+ * 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.activemq.bugs;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.List;
+
+import junit.framework.Assert;
+
+import org.apache.activemq.util.ClassLoadingAwareObjectInputStream;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Quick port to java to support AMQ build.
+ *
+ * This test demonstrates the classloader problem in the
+ * ClassLoadingAwareObjectInputStream impl. If the first interface in the proxy
+ * interfaces list is JDK and there are any subsequent interfaces that are NOT
+ * JDK interfaces the ClassLoadingAwareObjectInputStream will ignore their
+ * respective classloaders and cause the Proxy to throw an
+ * IllegalArgumentException because the core JDK classloader can't load the
+ * interfaces that are not JDK interfaces.
+ *
+ * See AMQ-3537
+ *
+ * @author jason.yankus
+ *
+ */
+@SuppressWarnings({ "rawtypes", "unchecked" })
+public class AMQ3537Test implements InvocationHandler, Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * If the first and second element in this array are swapped, the test will
+     * fail.
+     */
+    public static final Class[] TEST_CLASSES = new Class[] { List.class, NonJDKList.class,
Serializable.class };
+
+    /** Underlying list */
+    private List l = new ArrayList<String>();
+
+    @Before
+    public void setUp() throws Exception {
+        l.add("foo");
+    }
+
+    @Test
+    public void testDeserializeProxy() throws Exception {
+        // create the proxy
+        List proxy = (List) java.lang.reflect.Proxy.newProxyInstance(this.getClass().getClassLoader(),
TEST_CLASSES, this);
+
+        // serialize it
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        ObjectOutputStream oos = new ObjectOutputStream(baos);
+        oos.writeObject(proxy);
+        byte[] serializedProxy = baos.toByteArray();
+        oos.close();
+        baos.close();
+
+        // deserialize the proxy
+        ClassLoadingAwareObjectInputStream claois =
+            new ClassLoadingAwareObjectInputStream(new ByteArrayInputStream(serializedProxy));
+
+        // this is where it fails due to the rudimentary classloader selection
+        // in ClassLoadingAwareObjectInputStream
+        List deserializedProxy = (List) claois.readObject();
+
+        // assert the invocation worked
+        Assert.assertEquals("foo", deserializedProxy.get(0));
+    }
+
+    @Override
+    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+        return method.invoke(l, args);
+    }
+
+    public interface NonJDKList {
+        int size();
+    }
+}

Propchange: activemq/trunk/activemq-core/src/test/java/org/apache/activemq/bugs/AMQ3537Test.java
------------------------------------------------------------------------------
    svn:eol-style = native



Mime
View raw message