google-code-export / protostuff

Automatically exported from code.google.com/p/protostuff
Apache License 2.0
1 stars 1 forks source link

Protostuff corrupt objects when using generics combined with circular references #99

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
I am using protostuff binary with circular references and generics. As a very 
simplistic scenario i have the following classes:

    public class A {

    private String name;
    private B b;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public B getB() {
        return b;
    }

    public void setB(B b) {
        this.b = b;
        this.b.setA(this);
    }
}

///////////////////////////////////////////////////////////////////////////////

public class B {

    private String name;
    private A a;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public A getA() {
        return a;
    }

    public void setA(A a) {
        this.a = a;
    }
}

///////////////////////////////////////////////////////////////////////////////

public class Container<E> {
    private E element;
    private String name;

    public Container() {
    }

    public Container(E e, String name) {
        super();
        this.element = e;
        this.name = name;
    }

    public E getElement() {
        return element;
    }

    public void setElement(E e) {
        this.element = e;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

When i run the following unit test to check that the round trip serialisation / 
deserialisation has executed correctly i get a very odd result. the last 
assertion fails:

public class CircularRefTest {

    @Test
    public void testCircularReferences() {

        A a = new A();
        a.setName("a");
        B b = new B();
        b.setName("b");
        a.setB(b);
        Container<A> container = new Container<A>(a, "container");

        Schema<Container> schema = RuntimeSchema.getSchema(Container.class);
        LinkedBuffer buffer = LinkedBuffer.allocate(256);
        byte[] data = GraphIOUtil.toByteArray(container, schema, buffer);

        Container<A> copy = new Container<A>();
        GraphIOUtil.mergeFrom(data, copy, schema);

        assertEquals(container.getName(), copy.getName());
        assertEquals(container.getElement().getName(), copy.getElement().getName());
        assertEquals(container.getElement().getB().getName(), copy.getElement().getB().getName());

// something weird happens here with the circular references //here        
System.out.println(copy.getElement().getB().getA().getClass());
    assertTrue(copy.getElement().getB().getA() instanceof A); // fails
    }
}

Protostuff is corrupting the circular references from the child class back up 
to the parent. The last assertion should pass, but for some reason the class is 
of type Container.

What am i doing wrong ?

If i change the Container class to use strongly typed objects then the unit 
test passes. Is this a bug ??

The maven artifact i am using is:

<dependency>
        <groupId>com.dyuproject.protostuff</groupId>
        <artifactId>protostuff-api</artifactId>
        <version>1.0.4</version>
    </dependency>

Original issue reported on code.google.com by mchan...@hotmail.com on 2 Feb 2012 at 10:52

GoogleCodeExporter commented 9 years ago
I ran the test your provided and it did not fail for me.
What jvm version are you using (and on what platform)?

Original comment by david.yu...@gmail.com on 2 Feb 2012 at 11:30

GoogleCodeExporter commented 9 years ago
Im running on a windows 7 environment. JVM details are as follows: 

java version "1.6.0_24"
Java(TM) SE Runtime Environment (build 1.6.0_24-b07)
Java HotSpot(TM) Client VM (build 19.1-b02, mixed mode, sharing)

Original comment by mchan...@hotmail.com on 2 Feb 2012 at 12:23

GoogleCodeExporter commented 9 years ago
David, what JVM version and platform did you run the test on ? 

Original comment by mchan...@hotmail.com on 2 Feb 2012 at 12:24

GoogleCodeExporter commented 9 years ago
java version "1.6.0_26"
Java(TM) SE Runtime Environment (build 1.6.0_26-b03)
Java HotSpot(TM) 64-Bit Server VM (build 20.1-b02, mixed mode)

On Ubuntu 10.04 x64

Original comment by david.yu...@gmail.com on 2 Feb 2012 at 1:29

GoogleCodeExporter commented 9 years ago

I looked very carefully through the full list of dependencies in my project, i 
found the following: 

protostuff-api: 1.0.4
protostuff-collectionsschema: 1.0.2
protostuff-runtime: 1.0.2
protostuff-core: 1.0.2

I found that the 1.0.2 jars odd. I then deleted all the dependencies. 

I then added the following dependencies: 

  <dependency>
      <groupId>com.dyuproject.protostuff</groupId>
      <artifactId>protostuff-runtime</artifactId>
      <version>1.0.4</version>
    </dependency>
    <dependency>
      <groupId>com.dyuproject.protostuff</groupId>
      <artifactId>protostuff-core</artifactId>
      <version>1.0.4</version>
    </dependency>

This pulled in the following jars: 

protostuff-api: 1.0.4
protostuff-collectionsschema: 1.0.4
protostuff-runtime: 1.0.4
protostuff-core: 1.0.4

I then re ran the unit test & everything worked !

Just to double check i ran the unit test with all the jars based on version 
1.0.2, the test fails. 
It looks like this problem has been fixed in version 1.0.4

Thanks for your feedback in helping me diagnose the problem.

Original comment by mchan...@hotmail.com on 2 Feb 2012 at 2:36

GoogleCodeExporter commented 9 years ago
You should probably reference the versions as properties E.g 
${protostuff-version}
I'm glad you're able to find the problem and fixed it.

Cheers

Original comment by david.yu...@gmail.com on 2 Feb 2012 at 3:22