Asymmetric Serialization (Impossible Deserialization)

Hello,

I have a not so common, though possible useful situation that appears to be impossible to implement in JAVA.

The idea is like this: I would like to have a core functionality, which is programmed as a normal JAVA program and then extend it over time with several plug-ins. These plug-ins are delivered as .jar-files, objects are instantiated from classes in the .jar files (withjava.net.URLClassLoader), they have a state and can be stored in a serialized form. So far, so good, until...

... you want to deserialize the stored objects of classes that are not defined in the original program. The deserialization appears to use the system class loader and as the classes are not defined in the program (but in the .jar-files), any attempt to deserialize results in ajava.lang.ClassNotFoundException. Though, the objects are there!

You can create objects from .jar-files, you can store them, but you can't reload them. You see the assymetry? I think it is inconvenient. If anyone would know a way to load serialized objects for which the class definition is in .jar-files or explain why it has to be conceptually impossible, I would be very grateful,

thanks.

[1216 byte] By [toon_macharisa] at [2007-11-27 0:37:14]
# 1
see also http://forum.java.sun.com/thread.jspa?messageID=9604398
toon_macharisa at 2007-7-11 22:47:08 > top of Java-index,Core,Core APIs...
# 2

Actually, I found a solution here: http://forum.java.sun.com/thread.jspa?threadID=468339

I created the class

package test;

import java.io.IOException;

import java.io.InputStream;

import java.io.ObjectInputStream;

import java.io.ObjectStreamClass;

public class CustomObjectInputStream extends ObjectInputStream {

private ClassLoader classLoader;

public CustomObjectInputStream(InputStream in, ClassLoader classLoader) throws IOException {

super(in);

this.classLoader = classLoader;

}

protected Class<?> resolveClass(ObjectStreamClass desc) throws ClassNotFoundException {

return classLoader.loadClass(desc.getName());

}

}

and used it instead of the normal java.io.ObjectInputStream. It is as simple as that!

toon_macharisa at 2007-7-11 22:47:08 > top of Java-index,Core,Core APIs...
# 3

Beware that your code fails deserializing arrays under JRE 6.0. Under 5 all works fine, but using 6 yields a StreamCorruptedException. Change the resolveClass method to:

protected Class<?> resolveClass(ObjectStreamClass desc) throws ClassNotFoundException {

return Class.forName(desc.getName(), false, classLoader);

}

and you're safe.

camelCasea at 2007-7-11 22:47:08 > top of Java-index,Core,Core APIs...