-
Bug
-
Resolution: Fixed
-
P4
-
6
-
b45
-
sparc
-
solaris_9
Name: gm110360 Date: 06/14/2004
FULL PRODUCT VERSION :
java version "1.4.1_02"
ADDITIONAL OS VERSION INFORMATION :
SunOS sunny 5.9 Generic_112233-12 sun4u sparc SUNW,Sun-Fire-15000
A DESCRIPTION OF THE PROBLEM :
The sun ldap provider for JNDI resolves serialized objects using a custom implementation of ObjectInputStream ( com.sun.jndi.ldap.Obj.LoaderInputStream ).
This class correctly overrides ObjectInputStream.resolveClass to uses the correct codebases for a given directory entry; however, it does not override ObjectInputStream.resolveProxyClass. This means that interfaces for proxies are resolved using the local classpath, not that specified by the codebases.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
bind a proxy into an LDAP directory, with codebases set, then try to look it up where the proxied class is not in the local class path. The invocation handler will be sucessfuly deserialized, but the overall resolution will fail with ClassNotFound.
REPRODUCIBILITY :
This bug can be reproduced always.
CUSTOMER SUBMITTED WORKAROUND :
class Obj {
private static final class LoaderInputStream extends ObjectInputStream {
protected Class resolveClass(ObjectStreamClass desc)
throws IOException, ClassNotFoundException {
try {
return classLoader.loadClass(desc.getName());
} catch (ClassNotFoundException e) {
return super.resolveClass(desc);
}
}
protected Class resolveProxyClass(String[] interfaces) throws IOException, ClassNotFoundException {
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 = Class.forName(interfaces[i], false, classLoader);
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 : classLoader,
classObjs);
} catch (IllegalArgumentException e) {
throw new ClassNotFoundException(null, e);
}
}
private ClassLoader classLoader;
LoaderInputStream(InputStream in, ClassLoader cl)
throws IOException {
super(in);
classLoader = cl;
}
}
}
(Incident Review ID: 270728)
======================================================================