In a grails application, I needed to persist a complicated expression tree to the database, but I didn’t want to have Hibernate generate a database table for the information as it would greatly affect read performance (lots of joins) and I don’t need to have relational access to subsets of the tree. I decided to serialize the entire tree into a BLOB.
After creating a Hibernate userType to handle the serialization/deserialization, I ran into a ClassNotFoundException when attempting to deserialize my object. I found out that this is due to java using the “last defined ClassLoader” when deserializing with an ObjectInputStream, which might not be the right ClassLoader in a Groovy environment (see: http://jira.codehaus.org/browse/GROOVY-1627.
The solution? Subclass ObjectInputStream to allow you to pass in a predefined ClassLoader and override the resolveClass(ObjectStream classDesc) to use this ClassLoader parameter:
public class ClassLoaderAwareObjectInputStream extends ObjectInputStream {
private ClassLoader myClassLoader;
public ClassLoaderAwareObjectInputStream(ClassLoader myClassLoader) throws IOException, SecurityException {
super();
this.myClassLoader = myClassLoader;
}
public ClassLoaderAwareObjectInputStream(InputStream in, ClassLoader myClassLoader) throws IOException {
super(in);
this.myClassLoader = myClassLoader;
}
@Override
protected Class resolveClass(ObjectStreamClass desc) throws IOException,
ClassNotFoundException {
String name = desc.getName();
return Class.forName(name, false, myClassLoader);
}
}
Thanks to Satish Gunnu for the tip.