GSON JSON序列化-无法使字段private int java.sql.Timestamp.nanos可访问

yx2lnoni  于 7个月前  发布在  Java
关注(0)|答案(1)|浏览(89)

由于最近的Java升级,我们无法序列化从SQL数据库读取的对象,该数据库的值Map到java.sql.Timestamp。底层数据库是SAP Database,我们的客户能够用像Select getdate()这样简单的查询重现这个问题。
环境:Java 17.0.4.1,Eclipse插件,Mac OS X 14.0
我们不能添加add-opens=java.sql=ALL-UNNAMED或类似的东西。我还尝试在Gson库中调试TypeAdapterRuntimeTypeWrapper,发现java.sql.Timestamp对象使用了“反射适配器”。
作为一种变通方法,我现在使用Jackson库作为后备,它能够毫无问题地序列化我的对象(即下面代码中的第二个try子句可以毫无问题地工作):

try {
    json = GSON.toJson(object);
} catch (Exception e) {
    log.warn("Failed to serialize JSON. Trying alternative serializer (1).", e);
    try {
        json = new ObjectMapper().writeValueAsString(object);
    } catch (Exception e1) {
        log.warn("Failed to serialize JSON. Leaving null.", e);
    }
}

字符串
堆栈跟踪:

com.google.gson.JsonIOException: Failed making field 'java.sql.Timestamp#nanos' accessible; either increase its visibility or write a custom TypeAdapter for its declaring type.
    at com.google.gson.internal.reflect.ReflectionHelper.makeAccessible(ReflectionHelper.java:38)
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.getBoundFields(ReflectiveTypeAdapterFactory.java:286)
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.create(ReflectiveTypeAdapterFactory.java:130)
    at com.google.gson.Gson.getAdapter(Gson.java:556)
    at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:55)
    at com.google.gson.internal.bind.MapTypeAdapterFactory$Adapter.write(MapTypeAdapterFactory.java:207)
    at com.google.gson.internal.bind.MapTypeAdapterFactory$Adapter.write(MapTypeAdapterFactory.java:144)
    at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:70)
    at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.write(CollectionTypeAdapterFactory.java:97)
    at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.write(CollectionTypeAdapterFactory.java:61)
    at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:70)
    at com.google.gson.internal.bind.MapTypeAdapterFactory$Adapter.write(MapTypeAdapterFactory.java:207)
    at com.google.gson.internal.bind.MapTypeAdapterFactory$Adapter.write(MapTypeAdapterFactory.java:144)
    at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:70)
    at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.write(CollectionTypeAdapterFactory.java:97)
    at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.write(CollectionTypeAdapterFactory.java:61)
    at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:70)
    at com.google.gson.internal.bind.MapTypeAdapterFactory$Adapter.write(MapTypeAdapterFactory.java:207)
    at com.google.gson.internal.bind.MapTypeAdapterFactory$Adapter.write(MapTypeAdapterFactory.java:144)
    at com.google.gson.Gson.toJson(Gson.java:842)
    at com.google.gson.Gson.toJson(Gson.java:812)
    at com.google.gson.Gson.toJson(Gson.java:759)
    at com.google.gson.Gson.toJson(Gson.java:736)
Caused by: java.lang.reflect.InaccessibleObjectException: Unable to make field private int java.sql.Timestamp.nanos accessible: module java.sql does not "opens java.sql" to unnamed module @2554782d
    at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(Unknown Source)
    at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(Unknown Source)
    at java.base/java.lang.reflect.Field.checkCanSetAccessible(Unknown Source)
    at java.base/java.lang.reflect.Field.setAccessible(Unknown Source)
    at com.google.gson.internal.reflect.ReflectionHelper.makeAccessible(ReflectionHelper.java:35)

的数据
有什么想法吗?

vxbzzdmp

vxbzzdmp1#

看起来你必须编写自己的TypeAdapter。或者为失败的特定类型添加一个排除。在故障排除指南中发现:https://github.com/google/gson/blob/main/Troubleshooting.md#-inaccessibleobjectexception-module--does-not-opens--to-unnamed-module有确切的错误,你的解决方法看起来也很好。

相关问题