I'm using FastJSON to serialize and de-serialize some classes. However, I've found a combination that doesn't work: An exception that contains holds a reference to an object from another class cannot be de-serialized. Example:
import com.alibaba.fastjson.JSON;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;
public class Main {
@AllArgsConstructor
@Getter
@Setter
private static class A {
private String a;
private String b;
}
@AllArgsConstructor
@Getter
@Setter
private static class E extends Exception {
private A a;
}
public static void main(String[] args) {
E original = new E(new A("hello", "world"));
String serialized = JSON.toJSONString(original);
E deserialized = JSON.parseObject(serialized, E.class); // throws below exception
}
}
This example yields the following runtime error:
Exception in thread "main" com.alibaba.fastjson.JSONException: set property error, com.example.Main$E#a
at com.alibaba.fastjson.parser.deserializer.FieldDeserializer.setValue(FieldDeserializer.java:183)
at com.alibaba.fastjson.parser.deserializer.ThrowableDeserializer.deserialze(ThrowableDeserializer.java:149)
at com.alibaba.fastjson.parser.DefaultJSONParser.parseObject(DefaultJSONParser.java:688)
at com.alibaba.fastjson.JSON.parseObject(JSON.java:396)
at com.alibaba.fastjson.JSON.parseObject(JSON.java:300)
at com.alibaba.fastjson.JSON.parseObject(JSON.java:573)
at com.example.Main.main(Main2.java:40)
Caused by: java.lang.IllegalArgumentException: Can not set com.example.Main$A field com.example.Main$E.a to java.lang.Exception
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:167)
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:171)
at sun.reflect.UnsafeFieldAccessorImpl.ensureObj(UnsafeFieldAccessorImpl.java:58)
at sun.reflect.UnsafeObjectFieldAccessorImpl.set(UnsafeObjectFieldAccessorImpl.java:75)
at java.lang.reflect.Field.set(Field.java:764)
at com.alibaba.fastjson.parser.deserializer.FieldDeserializer.setValue(FieldDeserializer.java:178)
... 6 more
It tells me that it cannot set the field a
in E
to an Exception
object. It looks like a bug in FastJSON because I'd expect it to de-serialize the value of a
to an object of A
, not E
. Or did I made a mistake? What causes this problem and what has to be changed in order to circumvent this?