Details
-
Type: Bug
-
Status: Closed
-
Priority: Major
-
Resolution: Not A Bug
-
Affects Version/s: 1.4.2
-
Fix Version/s: None
-
Component/s: None
-
Labels:None
-
JDK version and platform:Sun 1.5.0_14 for Windows
Description
We are using OSGi (Equinox) with the following (simplified) scenario:
Plugin A has package AA (with a class AAA) and package AB (with a class ABA). AAA is not serialisable, has a no-arg constructor and a field of type ABA. Plugin B has a package BA with a class BAA. BAA extends AAA and implements Serializable. Additionally it provides its own readObject and writeObject for serialising the fields of AAA as specified by java.io.Serializable.
Equinox uses different classloaders for plugin A and B. Plugin A imports package AA but not AB. This works fine with Java serialisation not using XStream. This just calls the no-arg constructor of AAA which sets the field for ABA appropriately calling the constructor of ABA. Since AAA and ABA are in the same plugin, the classloader knows both classes.
When using XStream with the the SerializableConverter XStream wants to deserialise all fields of the non-serialisable class AAA. Instead of just calling the no-arg constructor of AAA it tries to instantiate ABA. Since XStream runs in the context of the classloader of plugin B, instantiating ABA fails since the package AB is not imported by plugin B.
Importing package AB is no option since this would make the imports of B highly dependent of the implementation of AAA. In our real scenario AAA has more than just one field depending on internal packages that are not imported by B.
Is this behaviour of XStream intended? It probably stems from http://jira.codehaus.org/browse/XSTR-266
Using an own converter for BAA circumvents this problem. However, this can get quite tedious when serialising a lot of classes from different plugins. A generic SerializableConverter in XStream behaving just like java.io.Serializable would be very helpful.
There's unfortunately nothing XStream can do about. Java serialization explicitly states that it does not call the constructors of the deserialized type. This is what XStream does.
However, you are right, that the spec also requires that the default-ctor of the first non-serializable parent is called, but actually this is JVM-internal magic and is nothing that can be done with the Java API itself. Or do you know, how an inherited constructor of an already existing object can be called?
XStream mimics Java serialization as close as possible, but it has its limits due to this internal stuff.
You might get away using the PureJavaReflectionProvider, but that's a question for the user's list.