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: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]