将Hibernate项目升级至Java 9遇模块依赖冲突问题求助
看起来你遇到的核心问题是Java 9模块系统的包可见性规则:它不允许两个不同模块导出完全相同的包,而java.sql和javax.transaction-api恰好都导出了javax.transaction.xa,再加上POM里的重复依赖,才引发了一系列连锁错误。下面是分步解决的方案:
第一步:清理重复的事务API依赖
你的POM里同时引入了org.jboss.spec.javax.transaction:jboss-transaction-api_1.2_spec和javax.transaction:javax.transaction-api,这两个都是JTA规范的实现包,属于重复依赖。建议保留jboss-transaction-api_1.2_spec(它是JBoss针对Java 9优化过的规范包),直接移除javax.transaction:javax.transaction-api依赖,避免重复类加载的问题。
第二步:调整module-info.java的模块声明
修改后的模块声明只保留必要的依赖,同时要注意开放Hibernate需要反射访问的实体类包(如果你的实体类在当前模块内):
module test { requires java.base; requires hibernate.core; requires javax.transaction; // 对应jboss-transaction-api的模块名称 requires java.sql; // 替换成你的实体类所在包,开放给Hibernate做反射操作 opens com.yourproject.entities to hibernate.core; }
第三步:解决javax.transaction.xa的包冲突(如果前两步后仍存在)
如果还是出现module reads package javax.transaction.xa from both java.sql and javax.transaction.api的错误,可以在运行时用--patch-module参数让javax.transaction模块复用java.sql提供的javax.transaction.xa包,避免重复导出:
java --patch-module javax.transaction=$JAVA_HOME/jmods/java.sql.jmod -m test/com.yourproject.MainClass
这个命令的作用是把java.sql模块里的javax.transaction.xa包"补丁"到javax.transaction模块中,让两个模块共享同一套包实现,消除冲突。
可选优化:升级Hibernate版本
你当前用的Hibernate 5.2.12.Final对Java 9模块系统的支持还比较基础,升级到5.3.x及以上版本(比如5.3.0.Final)会更省心——这些版本专门针对Java 9+的模块系统做了兼容性优化,能从根源减少这类包冲突问题。
内容的提问来源于stack exchange,提问作者Salem

