ASF Bugzilla – Attachment 27375 Details for
Bug 51647
Session replication fails with ClassNotFoundException when session attribute is Java dynamic proxy (java.lang.reflect.Proxy).
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Expanded patch
bug51647-tc5.5.patch (text/plain), 6.19 KB, created by
Mark Thomas
on 2011-08-11 11:49:22 UTC
(
hide
)
Description:
Expanded patch
Filename:
MIME Type:
Creator:
Mark Thomas
Created:
2011-08-11 11:49:22 UTC
Size:
6.19 KB
patch
obsolete
>Index: container/modules/cluster/src/share/org/apache/catalina/cluster/session/ReplicationStream.java >=================================================================== >--- container/modules/cluster/src/share/org/apache/catalina/cluster/session/ReplicationStream.java (revision 1156533) >+++ container/modules/cluster/src/share/org/apache/catalina/cluster/session/ReplicationStream.java (working copy) >@@ -22,6 +22,8 @@ > import java.io.IOException; > 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 >@@ -86,6 +88,43 @@ > } > } > >+ /** >+ * ObjectInputStream.resolveProxyClass has some funky way of using >+ * the incorrect class loader to resolve proxy classes, let's do it our way instead >+ */ >+ protected Class resolveProxyClass(String[] interfaces) >+ throws IOException, ClassNotFoundException { >+ >+ ClassLoader latestLoader = classLoader; >+ 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.findWebappClass(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 { > return Class.forName(name, false, getClass().getClassLoader()); >Index: container/modules/groupcom/src/share/org/apache/catalina/tribes/io/ReplicationStream.java >=================================================================== >--- container/modules/groupcom/src/share/org/apache/catalina/tribes/io/ReplicationStream.java (revision 1156533) >+++ container/modules/groupcom/src/share/org/apache/catalina/tribes/io/ReplicationStream.java (working copy) >@@ -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 >@@ -71,23 +73,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 >+ */ >+ 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 { > Class clazz = Class.forName(name, false, getClass().getClassLoader());
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 51647
:
27372
| 27375