protostuff
protostuff copied to clipboard
ProtostuffIOUtil.toByteArray stack overflow when there is reference loop in message
When there is an reference loop in the object map, the ProtostuffIOUtil.toByteArray
method will result in StackOverflowError
. Following are the steps to reproduce this phenomenon.
// 1. define 2 classes, A and B, referencing each other
static class A {
B b;
String name;
}
static class B {
A a;
String name;
}
public static void main(String[] args) {
// 2. create an object "a" and "b", with them referencing each other
A a = new A();
B b = new B();
a.name = "a";
b.name = "b";
a.b = b;
b.a = a;
// 3. try to get byte array for object "a".
Schema<A> schema = RuntimeSchema.getSchema(A.class);
LinkedBuffer buffer = LinkedBuffer.allocate(8192);
ProtostuffIOUtil.toByteArray(a, schema, buffer); // <-- this method call will result in StackOverflowError
}
Following is the top part of the error stack
Exception in thread "main" java.lang.StackOverflowError
at io.protostuff.ProtostuffOutput.writeObject(ProtostuffOutput.java:358)
at io.protostuff.runtime.RuntimeUnsafeFieldFactory$13$1.writeTo(RuntimeUnsafeFieldFactory.java:1048)
at io.protostuff.runtime.RuntimeSchema.writeTo(RuntimeSchema.java:475)
at io.protostuff.ProtostuffOutput.writeObject(ProtostuffOutput.java:363)
at io.protostuff.runtime.RuntimeUnsafeFieldFactory$13$1.writeTo(RuntimeUnsafeFieldFactory.java:1048)
at io.protostuff.runtime.RuntimeSchema.writeTo(RuntimeSchema.java:475)
at io.protostuff.ProtostuffOutput.writeObject(ProtostuffOutput.java:363)
at io.protostuff.runtime.RuntimeUnsafeFieldFactory$13$1.writeTo(RuntimeUnsafeFieldFactory.java:1048)
at io.protostuff.runtime.RuntimeSchema.writeTo(RuntimeSchema.java:475)
at io.protostuff.ProtostuffOutput.writeObject(ProtostuffOutput.java:363)
at io.protostuff.runtime.RuntimeUnsafeFieldFactory$13$1.writeTo(RuntimeUnsafeFieldFactory.java:1048)
at io.protostuff.runtime.RuntimeSchema.writeTo(RuntimeSchema.java:475)
at io.protostuff.ProtostuffOutput.writeObject(ProtostuffOutput.java:363)
at io.protostuff.runtime.RuntimeUnsafeFieldFactory$13$1.writeTo(RuntimeUnsafeFieldFactory.java:1048)
at io.protostuff.runtime.RuntimeSchema.writeTo(RuntimeSchema.java:475)
at io.protostuff.ProtostuffOutput.writeObject(ProtostuffOutput.java:363)
at io.protostuff.runtime.RuntimeUnsafeFieldFactory$13$1.writeTo(RuntimeUnsafeFieldFactory.java:1048)
at io.protostuff.runtime.RuntimeSchema.writeTo(RuntimeSchema.java:475)
at io.protostuff.ProtostuffOutput.writeObject(ProtostuffOutput.java:363)
at io.protostuff.runtime.RuntimeUnsafeFieldFactory$13$1.writeTo(RuntimeUnsafeFieldFactory.java:1048)
at io.protostuff.runtime.RuntimeSchema.writeTo(RuntimeSchema.java:475)
at io.protostuff.ProtostuffOutput.writeObject(ProtostuffOutput.java:363)
at io.protostuff.runtime.RuntimeUnsafeFieldFactory$13$1.writeTo(RuntimeUnsafeFieldFactory.java:1048)
at io.protostuff.runtime.RuntimeSchema.writeTo(RuntimeSchema.java:475)
at io.protostuff.ProtostuffOutput.writeObject(ProtostuffOutput.java:363)
at io.protostuff.runtime.RuntimeUnsafeFieldFactory$13$1.writeTo(RuntimeUnsafeFieldFactory.java:1048)
at io.protostuff.runtime.RuntimeSchema.writeTo(RuntimeSchema.java:475)
at io.protostuff.ProtostuffOutput.writeObject(ProtostuffOutput.java:363)
at io.protostuff.runtime.RuntimeUnsafeFieldFactory$13$1.writeTo(RuntimeUnsafeFieldFactory.java:1048)
at io.protostuff.runtime.RuntimeSchema.writeTo(RuntimeSchema.java:475)
at io.protostuff.ProtostuffOutput.writeObject(ProtostuffOutput.java:363)
at io.protostuff.runtime.RuntimeUnsafeFieldFactory$13$1.writeTo(RuntimeUnsafeFieldFactory.java:1048)
at io.protostuff.runtime.RuntimeSchema.writeTo(RuntimeSchema.java:475)
at io.protostuff.ProtostuffOutput.writeObject(ProtostuffOutput.java:363)
at io.protostuff.runtime.RuntimeUnsafeFieldFactory$13$1.writeTo(RuntimeUnsafeFieldFactory.java:1048)
at io.protostuff.runtime.RuntimeSchema.writeTo(RuntimeSchema.java:475)
at io.protostuff.ProtostuffOutput.writeObject(ProtostuffOutput.java:363)
at io.protostuff.runtime.RuntimeUnsafeFieldFactory$13$1.writeTo(RuntimeUnsafeFieldFactory.java:1048)
...
Use GraphIOUtil
instead of ProtostuffIOUtil
for data with circular references