SpringBoot+JavaFX项目Gson反序列化LocalDate遇权限及模块配置报错
解决Gson反序列化LocalDate/LocalTime时的模块权限问题
问题根源
你遇到的Unable to make field private final int java.time.LocalDate.year accessible错误,是因为Java 9+的模块系统默认禁止外部模块(比如Gson)通过反射访问java.base模块中java.time包的私有字段。而你之前修改module-info.java时错误地尝试开放不属于自己模块的java.base/java.time包,导致模块描述符无效,出现Package java.base not found in module错误。
最优解决方案:使用Gson官方Java 8时间适配器
Gson从2.8版本开始提供了专门的java-time模块,用于处理Java 8的日期时间类型(LocalDate、LocalTime等),无需依赖反射访问私有字段,彻底避开模块权限问题。
- 添加依赖
如果使用Maven,在pom.xml中添加:
<dependency> <groupId>com.google.code.gson</groupId> <artifactId>gson</artifactId> <version>2.10.1</version> </dependency> <dependency> <groupId>com.google.code.gson</groupId> <artifactId>gson-java8</artifactId> <version>2.10.1</version> </dependency>
Gradle用户则添加:
implementation 'com.google.code.gson:gson:2.10.1' implementation 'com.google.code.gson:gson-java8:2.10.1'
- 修改Gson实例创建代码
不要使用默认的new Gson(),而是注册JavaTimeModule:
Type avvisoListType = new TypeToken<ArrayList<Avviso>>(){}.getType(); // 注册JavaTimeModule后创建Gson实例 Gson gson = new GsonBuilder() .registerModule(new JavaTimeModule()) .create(); ArrayList<Avviso> avvisi = gson.fromJson(apiResponse.getBody().toString(), avvisoListType); return avvisi;
备选方案:通过JVM参数开放模块权限(不推荐生产环境)
如果暂时不想引入额外依赖,可以通过JVM启动参数允许Gson访问java.time的私有字段:
--add-opens java.base/java.time=com.google.gson
注意:这种方式依赖反射,可能在未来Java版本中被限制,仅适合临时调试。
关于module-info.java的正确用法
你之前的错误在于尝试开放不属于自己模块的java.base/java.time包——java.base是系统模块,你无法在自己的模块描述符中修改它的权限。如果你的Avviso类需要被Gson反射访问(比如有私有字段或无参构造),正确的module-info.java配置应该是开放你自己的包给Gson:
module mymodule { requires com.google.gson; // 开放你的Avviso类所在的包给Gson opens com.yourpackage.to.avviso to com.google.gson; }
(注:requires java.base可以省略,因为所有模块默认依赖java.base)
内容的提问来源于stack exchange,提问作者KarlKorr
相关产品推荐
相关产品推荐

