Closed GoogleCodeExporter closed 8 years ago
If you can attach a simple testcase, that would be great.
Original comment by david.yu...@gmail.com
on 25 Apr 2012 at 10:01
It seem to ProtoStuff can not cast the subClass rightly.
If there is a SuperClassCCC and a SubClassDDD (SubClassDDD extends
SuperClassCCC) and the pojo has a field declared by SuperClassCCC, the field of
pojo will be setted to SubClassDDD.
After deserializion, the field of new pojo will be SuperClassCCC not
SubClassDDD.
So the information of SubClass will be ignored by ProtoStuff .
Original comment by tully...@gmail.com
on 25 Apr 2012 at 10:01
You might have missed this on the wiki
(http://code.google.com/p/protostuff/wiki/ThingsYouNeedToKnow)
-Dprotostuff.runtime.morph_non_final_pojos=true
The side effect is that your other non-final pojos (even if there aren't any
subtypes) will be serialized with type metadata.
The workaround to that is simply making it final (no subtypes anyway)
Original comment by david.yu...@gmail.com
on 25 Apr 2012 at 10:15
the testcase is fllowing:
import org.junit.Test;
import com.dyuproject.protostuff.GraphIOUtil;
import com.dyuproject.protostuff.LinkedBuffer;
import com.dyuproject.protostuff.Schema;
import com.dyuproject.protostuff.runtime.RuntimeSchema;
public class TestSer {
public static class ExceptionA extends RuntimeException {
private static final long serialVersionUID = 2960474892574945398L;
public ExceptionA(String message, Throwable cause) {
super(message, cause);
}
public ExceptionA(String message) {
super(message);
}
public ExceptionA() {
super();
}
}
public static class ExceptionB extends RuntimeException {
private static final long serialVersionUID = 5191284136041381488L;
public ExceptionB(String message, Throwable cause) {
super(message, cause);
}
public ExceptionB(String message) {
super(message);
}
}
public static class Wrapper {
public Object getError() {
return error;
}
public void setError(Object error) {
this.error = error;
}
private Object error;
}
@Test
public void testSerException1() {
ExceptionB expB = new ExceptionB("ExceptionB");
ExceptionA expA = new ExceptionA("ExceptionA", expB);
Schema<ExceptionA> schema = RuntimeSchema.getSchema(ExceptionA.class);
System.out.println(expA.getCause());
// output TestSer$ExceptionB: ExceptionB
byte[] data = GraphIOUtil.toByteArray(expA, schema, LinkedBuffer.allocate(500));
ExceptionA cf = new ExceptionA();
GraphIOUtil.mergeFrom(data, cf, schema);
System.out.println(cf.getCause());// output null
}
@Test
public void testSerException2() {
ExceptionB expB = new ExceptionB("ExceptionB");
ExceptionA expA = new ExceptionA("ExceptionA", expB);
Wrapper wrapper = new Wrapper();
wrapper.setError(expA);
Schema<Wrapper> schema = RuntimeSchema.getSchema(Wrapper.class);
System.out.println(((ExceptionA) wrapper.getError()).getCause());
// output TestSer$ExceptionB: ExceptionB
byte[] data = GraphIOUtil.toByteArray(wrapper, schema, LinkedBuffer.allocate(500));
Wrapper wrappernew = new Wrapper();
GraphIOUtil.mergeFrom(data, wrappernew, schema);
System.out.println(((ExceptionA) wrappernew.getError()).getCause());// output
// null
}
}
Original comment by tully...@gmail.com
on 25 Apr 2012 at 10:55
And there is more strange case:
public static class ExceptionAA extends ExceptionA {
private static final long serialVersionUID = 2960474892574945391L;
public ExceptionAA(String message, Throwable cause) {
super(message, cause);
}
}
public static class ExceptionAAA extends ExceptionAA {
private static final long serialVersionUID = 2960474892574945394L;
public ExceptionAAA(String message, Throwable cause) {
super(message, cause);
}
}
@Test
public void testSerException3() {
ExceptionB expB = new ExceptionB("ExceptionB");
ExceptionAAA expA = new ExceptionAAA("ExceptionBiz", expB);
Wrapper wrapper = new Wrapper();
wrapper.setError(expA);
Schema<Wrapper> schema = RuntimeSchema.getSchema(Wrapper.class);
System.out.println(((ExceptionAAA) wrapper.getError()).getCause());
// output TestSer$ExceptionB: ExceptionB
byte[] data = GraphIOUtil.toByteArray(wrapper, schema, LinkedBuffer.allocate(500));
Wrapper wrappernew = new Wrapper();
GraphIOUtil.mergeFrom(data, wrappernew, schema);
System.out.println(((ExceptionAAA) wrappernew.getError()).getCause());// output
// java.lang.Throwable: ExceptionB
}
Original comment by tully...@gmail.com
on 25 Apr 2012 at 11:18
Add the snippet below:
static
{
System.setProperty("protostuff.runtime.morph_non_final_pojos", "true");
}
It is false by default (Some devs have the habit of not using the final
keyword).
I'll consider enabling that by default for 1.0.6.
Original comment by david.yu...@gmail.com
on 25 Apr 2012 at 11:49
It works. But I think protostuff should have something like ThrowableSerializer
and ThrowableDeserializer to process Throwable object
Original comment by tully...@gmail.com
on 25 Apr 2012 at 11:58
Makes sense. Code shall detect Throwable and make sure POLYMORPHIC_POJO is
used.
Original comment by david.yu...@gmail.com
on 25 Apr 2012 at 1:16
And this way can avoid using GraphIOUtil to process Throwable. Mostly we will
not design cyclic references object.
Original comment by tully...@gmail.com
on 26 Apr 2012 at 6:52
fixed @ rev 1520.
Throwables can now be serialized without using GraphIOUtil.
Original comment by david.yu...@gmail.com
on 2 May 2012 at 7:33
Original issue reported on code.google.com by
tully...@gmail.com
on 25 Apr 2012 at 9:45