我们有一个在 Java 11 上运行的 kotlin(版本 1.9.21)服务,我们计划迁移到 Java 17。但是面临与 Gson(版本 2.10.1)相关的错误
java.lang.AssertionError: java.lang.IllegalAccessException: class com.gilecode.yagson.com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$DefaultBoundField cannot access a member of class with modifiers "private final"
at com.gilecode.yagson.com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.write(ReflectiveTypeAdapterFactory.java:430)
at io.gsonfire.util.JsonUtils.toJsonTree(JsonUtils.java:60)
at io.gsonfire.gson.HooksTypeAdapter.write(HooksTypeAdapter.java:46)
at com.gilecode.yagson.com.google.gson.Gson.toJson(Gson.java:693)
at com.gilecode.yagson.com.google.gson.Gson.toJson(Gson.java:674)
at com.gilecode.yagson.com.google.gson.Gson.toJson(Gson.java:662)
at com.gilecode.yagson.com.google.gson.Gson.toJson(Gson.java:637)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:69)
at com.intellij.rt.junit.IdeaTestRunner$Repeater$1.execute(IdeaTestRunner.java:38)
at com.intellij.rt.execution.junit.TestsRepeater.repeat(TestsRepeater.java:11)
at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:35)
at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:232)
at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:55)
Caused by: java.lang.IllegalAccessException: class com.gilecode.yagson.com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$DefaultBoundField cannot access a member of class com.inin.wfm.api.dto.forecasting.shortterm.bu.StoredShortTermForecastResultResponseApi with modifiers "private final"
at java.base/jdk.internal.reflect.Reflection.newIllegalAccessException(Reflection.java:392)
at java.base/java.lang.reflect.AccessibleObject.checkAccess(AccessibleObject.java:674)
at java.base/java.lang.reflect.Field.checkAccess(Field.java:1102)
at java.base/java.lang.reflect.Field.get(Field.java:423)
at com.gilecode.yagson.com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$DefaultBoundField.getFieldValue(ReflectiveTypeAdapterFactory.java:226)
at com.gilecode.yagson.com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$DefaultBoundField.writeField(ReflectiveTypeAdapterFactory.java:278)
at com.gilecode.yagson.com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.write(ReflectiveTypeAdapterFactory.java:425)
java.lang.RuntimeException: Unable to invoke no-args constructor for class. Registering an InstanceCreator with Gson for this type may fix this problem.
at com.gilecode.yagson.com.google.gson.internal.ConstructorConstructor$17.construct(ConstructorConstructor.java:267)
at com.gilecode.yagson.com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.getInstance(ReflectiveTypeAdapterFactory.java:411)
at com.gilecode.yagson.com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.readOptionallyAdvisedInstance(ReflectiveTypeAdapterFactory.java:380)
at com.gilecode.yagson.adapters.TypeAdvisableComplexTypeAdapter.read(TypeAdvisableComplexTypeAdapter.java:51)
at io.gsonfire.gson.HooksTypeAdapter.deserialize(HooksTypeAdapter.java:91)
at io.gsonfire.gson.HooksTypeAdapter.read(HooksTypeAdapter.java:59)
at com.gilecode.yagson.refs.impl.ReferencesNoneModeContext.doRead(ReferencesNoneModeContext.java:62)
at com.gilecode.yagson.ReadContext.doRead(ReadContext.java:80)
at com.gilecode.yagson.com.google.gson.Gson.fromJson(Gson.java:915)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:69)
at com.intellij.rt.junit.IdeaTestRunner$Repeater$1.execute(IdeaTestRunner.java:38)
at com.intellij.rt.execution.junit.TestsRepeater.repeat(TestsRepeater.java:11)
at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:35)
at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:232)
at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:55)
Caused by: java.lang.UnsupportedOperationException: Cannot allocate class.
Caused by: java.lang.UnsupportedOperationException: Cannot allocate class Colgeneration
at com.gilecode.yagson.com.google.gson.internal.UnsafeAllocator$4.newInstance(UnsafeAllocator.java:108)
at com.gilecode.yagson.com.google.gson.internal.ConstructorConstructor$17.construct(ConstructorConstructor.java:261)
... 42 more
这是我们在多个文件中将 json 解析为对象的代码上下文
val cp = gson.fromJson(reader,RequiredClass::class.java)
这行用于将 json 解析为对象的代码在 Java 11 中运行良好,但在 Java 17 中则不然。
由于 Java 16 及更高版本取消了反射,Gson 是否与 Java 17 兼容。如果是,是否有任何经过验证的解决方法可以解决此错误。
一般来说,最新的 Gson 版本支持 Java 17 甚至 Java 21。但是,Gson 对尚未注册内置或自定义适配器的类使用反射。这些 JDK 版本强烈封装了 JDK 内部结构 (JEP 403)。因此,如果您之前(意外地)依赖于 JDK 类的基于反射的序列化,那么您将遇到
InaccessibleObjectException
并且必须为该类编写自定义 TypeAdapter
,请参阅 故障排除指南 了解更多信息.
补充几点:
com.gilecode.yagson.com.google.gson.Gson
。com.google.gson.Gson
来代替。