JDK17下Spring Boot 2.5.5集成MongoDB出现LocalDateTime反射访问异常
问题原因
该异常是JDK 9引入的模块化强封装机制导致的:java.time包下的非公开构造方法默认不允许未命名模块通过反射访问,而你当前使用的Spring Boot 2.5.5配套的Spring Data Commons 2.5.5版本尚未完成对JDK 17模块化限制的适配,会尝试反射调用LocalDateTime的私有构造方法完成属性映射,因此触发报错。该问题和Lombok无关,无需回退到Java 1.8,可通过以下方案解决。
可行解决方案
- 方案一:升级Spring Boot版本(最推荐)
Spring Boot 2.6.x及更高版本已经完成了JDK 17的适配,直接将Spring Boot版本升级到2.6.15、2.7.x等稳定版即可,无需修改业务代码即可解决该问题。 - 方案二:添加JVM启动参数绕过限制
如果暂时无法升级Spring Boot版本,可以在应用启动的VM参数中添加以下配置,开放java.time包的反射访问权限:
本地开发时将参数填入IDE的运行配置VM options栏,线上部署时添加到Java启动命令中即可。--add-opens java.base/java.time=ALL-UNNAMED - 方案三:自定义MongoDB类型转换器
手动实现LocalDateTime和MongoDB存储的Date类型的双向转换,避免Spring Data使用反射构造LocalDateTime实例:- 定义两个转换器类:
// LocalDateTime转Date的写入转换器 public class LocalDateTimeToDateConverter implements Converter<LocalDateTime, Date> { @Override public Date convert(LocalDateTime source) { return Date.from(source.atZone(ZoneId.systemDefault()).toInstant()); } } // Date转LocalDateTime的读取转换器 public class DateToLocalDateTimeConverter implements Converter<Date, LocalDateTime> { @Override public LocalDateTime convert(Date source) { return LocalDateTime.ofInstant(source.toInstant(), ZoneId.systemDefault()); } }- 将转换器注册到MongoDB配置中:
@Configuration public class MongoConfig extends AbstractMongoClientConfiguration { @Override protected String getDatabaseName() { return "你的数据库名"; } @Override public MongoCustomConversions customConversions() { List<Converter<?, ?>> converters = new ArrayList<>(); converters.add(new LocalDateTimeToDateConverter()); converters.add(new DateToLocalDateTimeConverter()); return new MongoCustomConversions(converters); } }
内容的提问来源于stack exchange,提问作者Armen Arzumanyan
相关产品推荐
相关产品推荐

