tomcat-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From fha...@apache.org
Subject svn commit: r645184 - /tomcat/trunk/java/org/apache/catalina/tribes/io/ReplicationStream.java
Date Sat, 05 Apr 2008 22:04:09 GMT
Author: fhanik
Date: Sat Apr  5 15:03:59 2008
New Revision: 645184

URL: http://svn.apache.org/viewvc?rev=645184&view=rev
Log:
Fix for bug
https://issues.apache.org/bugzilla/show_bug.cgi
The ObjectInputStream.resolveProxyClass uses some funky native code base to retrieve what
class loader to use, and it doesn't return the correct one. So we have to mimic the behavior
in that class but use our class loaders instead


Modified:
    tomcat/trunk/java/org/apache/catalina/tribes/io/ReplicationStream.java

Modified: tomcat/trunk/java/org/apache/catalina/tribes/io/ReplicationStream.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/tribes/io/ReplicationStream.java?rev=645184&r1=645183&r2=645184&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/tribes/io/ReplicationStream.java (original)
+++ tomcat/trunk/java/org/apache/catalina/tribes/io/ReplicationStream.java Sat Apr  5 15:03:59
2008
@@ -22,6 +22,8 @@
 import java.io.InputStream;
 import java.io.ObjectInputStream;
 import java.io.ObjectStreamClass;
+import java.lang.reflect.Modifier;
+import java.lang.reflect.Proxy;
 
 /**
  * Custom subclass of <code>ObjectInputStream</code> that loads from the
@@ -42,7 +44,6 @@
      */
     private ClassLoader[] classLoaders = null;
     
-
     /**
      * Construct a new instance of CustomObjectInputStream
      *
@@ -71,22 +72,68 @@
     public Class resolveClass(ObjectStreamClass classDesc)
         throws ClassNotFoundException, IOException {
         String name = classDesc.getName();
-        boolean tryRepFirst = name.startsWith("org.apache.catalina.tribes");
         try {
-            try
-            {
-                if ( tryRepFirst ) return findReplicationClass(name);
-                else return findExternalClass(name);
-            }
-            catch ( Exception x )
-            {
-                if ( tryRepFirst ) return findExternalClass(name);
-                else return findReplicationClass(name);
-            }
+            return resolveClass(name);
         } catch (ClassNotFoundException e) {
             return super.resolveClass(classDesc);
         }
     }
+    
+    public Class resolveClass(String name)
+        throws ClassNotFoundException, IOException {
+
+        boolean tryRepFirst = name.startsWith("org.apache.catalina.tribes");
+            try {
+            if (tryRepFirst)
+                return findReplicationClass(name);
+            else
+                return findExternalClass(name);
+        } catch (Exception x) {
+            if (tryRepFirst)
+                return findExternalClass(name);
+            else
+                return findReplicationClass(name);
+        }
+    }
+    
+    /**
+     * ObjectInputStream.resolveProxyClass has some funky way of using 
+     * the incorrect class loader to resolve proxy classes, let's do it our way instead
+     */
+    @Override
+    protected Class<?> resolveProxyClass(String[] interfaces)
+            throws IOException, ClassNotFoundException {
+        
+        ClassLoader latestLoader = (classLoaders!=null && classLoaders.length==0)?null:classLoaders[0];
+        ClassLoader nonPublicLoader = null;
+        boolean hasNonPublicInterface = false;
+
+        // define proxy in class loader of non-public interface(s), if any
+        Class[] classObjs = new Class[interfaces.length];
+        for (int i = 0; i < interfaces.length; i++) {
+            Class cl = this.resolveClass(interfaces[i]);
+            if (latestLoader==null) latestLoader = cl.getClassLoader();
+            if ((cl.getModifiers() & Modifier.PUBLIC) == 0) {
+                if (hasNonPublicInterface) {
+                    if (nonPublicLoader != cl.getClassLoader()) {
+                        throw new IllegalAccessError(
+                                "conflicting non-public interface class loaders");
+                    }
+                } else {
+                    nonPublicLoader = cl.getClassLoader();
+                    hasNonPublicInterface = true;
+                }
+            }
+            classObjs[i] = cl;
+        }
+        try {
+            return Proxy.getProxyClass(hasNonPublicInterface ? nonPublicLoader
+                    : latestLoader, classObjs);
+        } catch (IllegalArgumentException e) {
+            throw new ClassNotFoundException(null, e);
+        }
+    }
+
     
     public Class findReplicationClass(String name)
         throws ClassNotFoundException, IOException {



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org


Mime
View raw message