Spring Boot中使用JMapper触发异常的问题求助
解决Java 17下JMapper与XStream兼容的InaccessibleObjectException异常
问题原因
你使用的JMapper 1.6.1.CR1依赖的XStream版本为1.4.9,该版本未适配Java 9+引入的模块系统(JPMS)。当XStream尝试通过反射访问java.util.TreeMap的私有字段时,Java 17的模块安全机制会直接阻止这种访问,从而抛出InaccessibleObjectException。
解决方案
方案1:升级JMapper到兼容Java 17的版本
JMapper后续版本(如1.6.2及以上)已更新依赖的XStream版本,适配了JPMS规范。修改项目依赖配置:
- Maven示例:
<dependency> <groupId>com.googlecode.jmapper-framework</groupId> <artifactId>jmapper-core</artifactId> <version>1.6.2</version> </dependency>
- Gradle示例:
implementation 'com.googlecode.jmapper-framework:jmapper-core:1.6.2'
方案2:添加JVM启动参数(临时 workaround)
若暂时无法升级JMapper,可通过添加JVM参数放宽模块访问限制:
--add-opens java.base/java.util=ALL-UNNAMED --add-opens java.base/java.lang.reflect=ALL-UNNAMED
- IDE启动:在运行配置的VM参数中添加上述内容
- Jar包启动:
java --add-opens java.base/java.util=ALL-UNNAMED --add-opens java.base/java.lang.reflect=ALL-UNNAMED -jar your-app.jar
方案3:替换为更主流的映射工具(长期推荐)
如果JMapper的维护状态无法满足需求,可替换为支持Java 17的主流映射工具,比如:
- MapStruct:编译时生成映射代码,性能优异,兼容性强
- ModelMapper:运行时映射,配置灵活
以MapStruct为例实现你的映射需求:
- 添加依赖:
<dependency> <groupId>org.mapstruct</groupId> <artifactId>mapstruct</artifactId> <version>1.5.5.Final</version> </dependency> <dependency> <groupId>org.mapstruct</groupId> <artifactId>mapstruct-processor</artifactId> <version>1.5.5.Final</version> <scope>provided</scope> </dependency>
- 定义映射接口:
@Mapper(componentModel = "spring") public interface TodoItemMapper { TodoItemMapper INSTANCE = Mappers.getMapper(TodoItemMapper.class); TodoItemDto toDto(TodoItem todoItem); }
- 业务代码中使用:
Optional<TodoItem> result = todoRepository.findById(id); TodoItemDto res = result.map(TodoItemMapper.INSTANCE::toDto).orElse(null);
额外代码修正
你的原代码中存在一个小问题:mapper.getDestination(result)传递的是Optional<TodoItem>,但JMapper的getDestination方法需要实体对象,需先处理Optional:
TodoItemDto res = result.map(todoItem -> mapper.getDestination(todoItem)).orElse(null);
内容的提问来源于stack exchange,提问作者Navid_pdp11
相关产品推荐
相关产品推荐

