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

问题描述 投票:0回答:1

自从最近的 Java 升级以来,我们无法序列化从 SQL 数据库读取的对象,并将值映射到

java.sql.Timestamp
。底层数据库是 SAP Sybase,我们的客户能够通过像
Select getdate()
这样简单的查询来重现问题。

环境:Java 17.0.4.1、Eclipse Adoptium、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)

有什么想法吗?

java json jackson gson sybase
1个回答
0
投票

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

© www.soinside.com 2019 - 2024. All rights reserved.