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

Key: XSTR-407
Type: Bug Bug
Status: Closed Closed
Resolution: Fixed
Priority: Major Major
Assignee: Joerg Schaible
Reporter: Jerzy Smyczek
Votes: 0
Watchers: 0
Operations

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

Comparing uninitialized objects

Created: 12/Jun/07 10:41 AM   Updated: 25/Feb/08 05:01 PM
Component/s: Converters, Core
Affects Version/s: 1.2.2
Fix Version/s: 1.3

JDK version and platform: Sun 1.5.0_11 for Windows


 Description  « Hide
Below is the minimal case for the problem I came across. During deserialization NPE is thrown from compareTo method, probably because object is put in the tree before id is filled. Simple workaround is to change the order of the fields, but sometimes it's not possible (for example when field is inherited).

import java.util.Set;
import java.util.TreeSet;
import junit.framework.TestCase;
import com.thoughtworks.xstream.XStream;

public class Test extends TestCase {
    XStream xs = new XStream();

    public void test() {
        C c = new C(1);
        c.others.add(c);
        c.others.add(new C(2));
        xs.fromXML(xs.toXML(c));
    }
}

class C implements Comparable {
    Set<C> others = new TreeSet<C>();
    final Integer id;

    C(Integer id) {
        this.id = id;
    }

    public int compareTo(Object o) {
        return id.compareTo(((C) o).id);
    }
}

 All   Comments   Change History      Sort Order: Ascending order - Click to sort in descending order
Joerg Schaible - 12/Jun/07 10:56 AM
Since XStream 1.2.2 you can set the order in which the fields are saved (see FAQ). Starting with 1.3 the inherited fields will be saved first (see announcement of 1.2.2 release).

Jerzy Smyczek - 13/Jun/07 06:40 AM
This modified case fails regardless of field order:

import java.util.Set;
import java.util.TreeSet;
import junit.framework.TestCase;
import com.thoughtworks.xstream.XStream;

public class Test extends TestCase {
    XStream xs = new XStream();

    public void test() {
        C c = new C(1);
        c.others.add(c);
        c.others.add(new C(1)); /* same id */
        xs.fromXML(xs.toXML(c));
    }
}

class C implements Comparable {
    final Integer id;
    final Set<C> others = new TreeSet<C>();

    C(Integer id) {
        this.id = id;
    }

    public int compareTo(Object o) {
        C c = (C) o;
        int cmp = id.compareTo(c.id);
        if (cmp != 0) {
            return cmp;
        } else {
            return new Integer(others.size()).compareTo(c.others.size());
        }
    }
}

Joerg Schaible - 19/Sep/07 05:58 PM
You're right, your second case also failed with the head revision. I've tested the same case with JDK serialization and had to recognize that they succeed. Main reason was, that the JDK contains an optimized functionality when a presorted set is added into an empty TreeSet. I changed the implementation of the TreeSetConverter (and TreeMapConverter) to behave the same. You may give the latest head revision a try.

Joerg Schaible - 25/Feb/08 05:01 PM
Closing issues before next release.