History | Log In     View a printable version of the current page.  
Issue Details (XML | Word | Printable)

Key: XSTR-320
Type: Bug Bug
Status: Closed Closed
Resolution: Fixed
Assignee: Unassigned
Reporter: Ali Ranalvi
Votes: 0
Watchers: 1
Operations

If you were logged in you would be able to see more operations.
XStream

Unable to distinguish between static variable and another variable from super class during unmarshalling

Created: 13/Jun/06 05:23 AM   Updated: 24/May/07 12:38 AM
Component/s: None
Affects Version/s: None
Fix Version/s: 1.2.2

File Attachments: 1. Zip Archive junit_test.zip (3 kb)
2. Text File XSTR-320-DRAFT.patch (4 kb)


JDK version and platform: Sun_1.5.0_06


 Description  « Hide
I'm trying to use XStream to persist a toolkit-auto-generated Java class to XML and retrieve it when required.

For lucidity, here's a skeletal look of what the generated classes look like:

final public class CHSMTestClass {

public CHSMTestClass() {
myCluster = new Cluster();
}

static public abstract class Parent {

protected Parent(int[] children)
{
children_ = children;
}
private final int[] children_; // <----------------
}

static public class Cluster extends Parent {
private static int[] children_ = new int[] { 0, 1, 2, 3 }; // <----------------
public Cluster()
{
super(children_);
activeChild_ = lastChild_ = null;
history_ = false;
}

private final boolean history_;
private String activeChild_;
private String lastChild_;
}
final public Cluster myCluster;
}

Notice that there exist 2 variables called "children_" : the first being a static class variable of Cluster and the other being a private variable of Parent.

XStream generates the following XML file:

<test.mblox.xstream.CHSMTestClass>
  <myCluster>
    <history__>false</history__>
    <children__>
      <int>0</int>
      <int>1</int>
      <int>2</int>
      <int>3</int>
    </children__>
  </myCluster>
</test.mblox.xstream.CHSMTestClass>

Now during unmarshalling, XStream is unable to distinguish the static class member "children_" from a similarly named variable derived from the super class Parent. It tries to set the static class variable and hence the following exceptions:

Exception in thread "main" com.thoughtworks.xstream.converters.ConversionException: Could not set field class test.mblox.xstream.CHSMTestClass$Cluster.children_ : null
---- Debugging information ----
required-type : test.mblox.xstream.CHSMTestClass$Cluster
cause-message : Could not set field class test.mblox.xstream.CHSMTestClass$Cluster.children_ : null
class : test.mblox.xstream.CHSMTestClass
message : Could not set field class test.mblox.xstream.CHSMTestClass$Cluster.children_ : null
path : /test.mblox.xstream.CHSMTestClass/myCluster/children__
cause-exception : com.thoughtworks.xstream.converters.reflection.ObjectAccessException
-------------------------------
at com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:45)
at com.thoughtworks.xstream.core.ReferenceByXPathUnmarshaller.convertAnother(ReferenceByXPathUnmarshaller.java:39)
at com.thoughtworks.xstream.converters.reflection.ReflectionConverter.unmarshal(ReflectionConverter.java:103)
at com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:38)
at com.thoughtworks.xstream.core.ReferenceByXPathUnmarshaller.convertAnother(ReferenceByXPathUnmarshaller.java:39)
at com.thoughtworks.xstream.core.TreeUnmarshaller.start(TreeUnmarshaller.java:99)
at com.thoughtworks.xstream.core.ReferenceByXPathMarshallingStrategy.unmarshal(ReferenceByXPathMarshallingStrategy.java:12)
at com.thoughtworks.xstream.XStream.unmarshal(XStream.java:552)
at com.thoughtworks.xstream.XStream.unmarshal(XStream.java:540)
at com.thoughtworks.xstream.XStream.fromXML(XStream.java:524)
at test.mblox.xstream.MyXStreamTestClass.deserializeDummyClassObject(MyXStreamTestClass.java:81)
at test.mblox.xstream.MyXStreamTestClass.main(MyXStreamTestClass.java:34)
Caused by: com.thoughtworks.xstream.converters.reflection.ObjectAccessException: Could not set field class test.mblox.xstream.CHSMTestClass$Cluster.children_ : null
at com.thoughtworks.xstream.converters.reflection.Sun14ReflectionProvider.write(Sun14ReflectionProvider.java:102)
at com.thoughtworks.xstream.converters.reflection.Sun14ReflectionProvider.writeField(Sun14ReflectionProvider.java:67)
at com.thoughtworks.xstream.converters.reflection.ReflectionConverter.unmarshal(ReflectionConverter.java:106)
at com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:38)
... 11 more
Caused by: java.lang.IllegalArgumentException
at sun.misc.Unsafe.objectFieldOffset(Native Method)
at com.thoughtworks.xstream.converters.reflection.Sun14ReflectionProvider.write(Sun14ReflectionProvider.java:73)
... 14 more

------------

Elementary JUnit test cases attached with this bug report

 All   Comments   Change History      Sort Order: Ascending order - Click to sort in descending order
Cyrille Le Clerc - 18/Jun/06 03:44 AM
This problem seems to be related to the FieldDictionary that also registers non serializable fields (transient and static). Due to this, the deserializer tries to access the wrong field.

Here is a patch proposal with an associated test case. The main modification is to skip registration of the non serializable fields (ie static and transient fields) in the FieldDictionary.

Joerg Schaible - 17/May/07 03:58 PM
Hi Ali,

I've committed a change, that solves this issue. Feel free to build a version from teh subversion repository and repoert back if it works for you.

- Jörg