无法使字段“属性”可访问;更改其可见性或为其声明类型 gSON fromJson 编写自定义 TypeAdapter

Aby*_*zar 6 java gson

我有一个名为游戏的课程:

public class Game {
    private String name;
    private int id;
    private GameFields[] gameFields;

    @Expose(deserialize = false)
    public ArrayList<Player> players = new ArrayList<>();

    public Game() {

    }

    public Game(String name, int id, GameFields[] gameFields) {
        this.name = name;
        this.id = id;
        this.gameFields = gameFields;
    }
}
Run Code Online (Sandbox Code Playgroud)

我想使用 GSON.fromJson 方法为此类创建对象。但问题是方法返回

Failed to make field 'com.example.Models.Game#name' accessible; either change its visibility or write a custom TypeAdapter for its declaring type
Run Code Online (Sandbox Code Playgroud)

这就是我调用该方法的方式

Gson gson = new Gson();
Game object = null;
try {
    object = gson.fromJson("{\"name\":\"test\",\"id\":1}", Game.class);
}catch (JsonParseException e){
    System.out.println(e.getMessage());
}
Run Code Online (Sandbox Code Playgroud)

我不知道为什么会发生这种情况,因为在我看到的每个示例中,用户都对其字段使用了私有可见性。但就我而言,只有当我将字段的可见性更改为“公共”时,它才有效。

更新

整个堆栈跟踪:

com.google.gson.JsonIOException: Failed making field 'com.example.server.Models.Game#name' accessible; either change its visibility or write a custom TypeAdapter for its declaring type
    at com.google.gson@2.9.0/com.google.gson.internal.reflect.ReflectionHelper.makeAccessible(ReflectionHelper.java:22)
    at com.google.gson@2.9.0/com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.getBoundFields(ReflectiveTypeAdapterFactory.java:158)
    at com.google.gson@2.9.0/com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.create(ReflectiveTypeAdapterFactory.java:101)
    at com.google.gson@2.9.0/com.google.gson.Gson.getAdapter(Gson.java:501)
    at com.google.gson@2.9.0/com.google.gson.Gson.fromJson(Gson.java:990)
    at com.google.gson@2.9.0/com.google.gson.Gson.fromJson(Gson.java:956)
    at com.google.gson@2.9.0/com.google.gson.Gson.fromJson(Gson.java:905)
    at com.google.gson@2.9.0/com.google.gson.Gson.fromJson(Gson.java:876)
    at com.example.server/com.example.server.Server$2.onData(Server.java:55)
    at com.example.server/com.example.server.Server$2.onData(Server.java:44)
    at netty.socketio@1.7.18/com.corundumstudio.socketio.namespace.Namespace.onEvent(Namespace.java:146)
    at netty.socketio@1.7.18/com.corundumstudio.socketio.handler.PacketListener.onPacket(PacketListener.java:106)
    at netty.socketio@1.7.18/com.corundumstudio.socketio.handler.InPacketHandler.channelRead0(InPacketHandler.java:92)
    at netty.socketio@1.7.18/com.corundumstudio.socketio.handler.InPacketHandler.channelRead0(InPacketHandler.java:36)
    at io.netty.channel.SimpleChannelInboundHandler.channelRead(SimpleChannelInboundHandler.java:99)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:377)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:363)
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:355)
    at io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:102)
    at io.netty.handler.codec.MessageToMessageCodec.channelRead(MessageToMessageCodec.java:111)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:377)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:363)
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:355)
    at io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:102)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:377)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:363)
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:355)
    at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:294)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:377)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:363)
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:355)
    at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1410)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:377)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:363)
    at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:919)
    at netty.socketio@1.7.18/com.corundumstudio.socketio.transport.PollingTransport.onPost(PollingTransport.java:161)
    at netty.socketio@1.7.18/com.corundumstudio.socketio.transport.PollingTransport.handleMessage(PollingTransport.java:120)
    at netty.socketio@1.7.18/com.corundumstudio.socketio.transport.PollingTransport.channelRead(PollingTransport.java:97)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:377)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:363)
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:355)
    at netty.socketio@1.7.18/com.corundumstudio.socketio.handler.AuthorizeHandler.channelRead(AuthorizeHandler.java:137)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:377)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:363)
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:355)
    at io.netty.channel.SimpleChannelInboundHandler.channelRead(SimpleChannelInboundHandler.java:102)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:377)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:363)
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:355)
    at io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:102)
    at io.netty.handler.codec.MessageToMessageCodec.channelRead(MessageToMessageCodec.java:111)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:377)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:363)
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:355)
    at io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:102)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:377)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:363)
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:355)
    at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:316)
    at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:290)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:377)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:363)
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:355)
    at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1410)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:377)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:363)
    at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:919)
    at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:163)
    at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:714)
    at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:650)
    at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:576)
    at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:493)
    at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:989)
    at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
    at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
    at java.base/java.lang.Thread.run(Thread.java:833)
Caused by: java.lang.reflect.InaccessibleObjectException: Unable to make field private java.lang.String com.example.server.Models.Game.name accessible: module com.example.server does not "opens com.example.server.Models" to module com.google.gson
    at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:354)
    at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:297)
    at java.base/java.lang.reflect.Field.checkCanSetAccessible(Field.java:180)
    at java.base/java.lang.reflect.Field.setAccessible(Field.java:174)
    at com.google.gson@2.9.0/com.google.gson.internal.reflect.ReflectionHelper.makeAccessible(ReflectionHelper.java:19)
    ... 75 more
Run Code Online (Sandbox Code Playgroud)

Aby*_*zar 9

我通过添加以下行解决了该问题:

opens com.example.server.Models to com.google.gson;
Run Code Online (Sandbox Code Playgroud)

module-info.java

  • 这适用于java 11及以上版本 (3认同)

Pra*_*rma 5

在 java 升级版本 11 到 17 期间,我在使用 gson 反序列化 java.time.Instant 时遇到了同样的问题,请参阅 gson 文档以了解发生这种情况的原因: https: //github.com/google/gson/blob/main/ UserGuide.md#gsons-expose

解决方案: 使用以下命令创建 Gson:new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create()

例子:

Gson gson = new GsonBuilder().setPrettyPrinting()
            .excludeFieldsWithoutExposeAnnotation()
            .create();
Run Code Online (Sandbox Code Playgroud)