我们正在使用 FST(快速序列化)将大量对象同时放入磁盘,然后读取它们。对象本身具有复杂的结构并包含不包含的内容:基元、复杂类型、数组和它们的集合。问题是,使用默认 FST 配置 ( FSTConfiguration.createDefaultConfiguration()
) 我们会遇到反序列化异常,如下所示:
java.lang.reflect.InvocationTargetException: null
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_91]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_91]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_91]
at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_91]
at org.nustaq.serialization.FSTObjectInput.readObjectCompatibleRecursive(FSTObjectInput.java:609) ~[fst-2.55.jar:na]
at org.nustaq.serialization.FSTObjectInput.readObjectCompatibleRecursive(FSTObjectInput.java:598) ~[fst-2.55.jar:na]
at org.nustaq.serialization.FSTObjectInput.readObjectCompatible(FSTObjectInput.java:574) ~[fst-2.55.jar:na]
at org.nustaq.serialization.FSTObjectInput.instantiateAndReadNoSer(FSTObjectInput.java:559) ~[fst-2.55.jar:na]
at org.nustaq.serialization.FSTObjectInput.readObjectWithHeader(FSTObjectInput.java:374) ~[fst-2.55.jar:na]
at org.nustaq.serialization.FSTObjectInput.readObjectInternal(FSTObjectInput.java:331) ~[fst-2.55.jar:na]
at org.nustaq.serialization.serializers.FSTCollectionSerializer.instantiate(FSTCollectionSerializer.java:92) ~[fst-2.55.jar:na]
at org.nustaq.serialization.FSTObjectInput.instantiateAndReadWithSer(FSTObjectInput.java:501) ~[fst-2.55.jar:na]
at org.nustaq.serialization.FSTObjectInput.readObjectWithHeader(FSTObjectInput.java:370) ~[fst-2.55.jar:na]
at org.nustaq.serialization.FSTObjectInput.readObjectFields(FSTObjectInput.java:712) ~[fst-2.55.jar:na]
at org.nustaq.serialization.FSTObjectInput.instantiateAndReadNoSer(FSTObjectInput.java:566) ~[fst-2.55.jar:na]
at org.nustaq.serialization.FSTObjectInput.readObjectWithHeader(FSTObjectInput.java:374) ~[fst-2.55.jar:na]
at org.nustaq.serialization.FSTObjectInput.readObjectInternal(FSTObjectInput.java:331) ~[fst-2.55.jar:na]
at org.nustaq.serialization.FSTObjectInput.readObject(FSTObjectInput.java:311) ~[fst-2.55.jar:na]
at com.agilertech.graph.dao.disk.readers.EntityStorageReader.readObject(EntityStorageReader.java:21) ~[main/:na]
...our code there...
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) ~[na:1.8.0_91]
at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:308) ~[na:1.8.0_91]
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:180) ~[na:1.8.0_91]
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:294) ~[na:1.8.0_91]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) ~[na:1.8.0_91]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) ~[na:1.8.0_91]
at java.lang.Thread.run(Thread.java:745) ~[na:1.8.0_91]
Caused by: java.io.InvalidObjectException: can't deserialize enum
at java.lang.Enum.readObject(Enum.java:251) ~[na:1.8.0_91]
... 35 common frames omitted
这发生在大约 100 次中的 5 次。虽然,如果切换到 JSON 配置 ( FSTConfiguration.createJsonConfiguration()
),所有问题都消失了——在(反)序列化期间根本没有例外。
我试图通过调试找到根本原因,看起来在某些情况下 FSTuseCompatibleMode
出于某种原因切换到然后尝试通过反序列化来实例化Enum
它。我也试图重现这个问题作为测试,但没有得到任何运气——我正在创建的可比较的数据结构不会导致此类问题。
我们的域结构/FST 使用不当是否存在问题,或者可能是错误?
请注意,我们使用的所有域类都正确实现了Serializable
.