Hibernate运行报ExceptionInInitializerError及java.base模块访问错误求解
你遇到的报错是Java 9及以上版本引入的模块化系统(JPMS)限制导致的,你当前使用的Hibernate版本较低(从代码中使用的AnnotationConfiguration可判断为Hibernate 3.x系列),依赖的cglib字节码工具会通过反射调用JDK内部的java.lang.ClassLoader的defineClass方法,而JPMS默认禁止未命名模块访问java.base模块下的内部API,因此触发该异常。
解决方案
方案1:降级JDK版本(最稳妥,无需修改代码)
老版本Hibernate 3.x仅官方支持到JDK 8,直接将本地运行环境切换为JDK 8即可完全解决该报错,无需调整任何代码和配置。
方案2:添加JVM启动参数(保留现有JDK版本)
如果不想降级JDK,可以在程序启动时添加JVM参数,放开模块化的访问限制:
--add-opens java.base/java.lang=ALL-UNNAMED
如果后续出现其他类似的模块化访问报错,可以继续补充对应的参数,例如:
--add-opens java.base/java.util=ALL-UNNAMED --add-opens java.base/java.math=ALL-UNNAMED
配置方式:如果是IDEA开发环境,打开
Run/Debug Configurations,找到对应主类的配置,在VM options输入框中粘贴上述参数即可;Eclipse等其他IDE操作逻辑类似。
方案3:升级Hibernate版本(适配高版本JDK的长期方案)
升级到Hibernate 5.x或6.x的最新稳定版本,新版本已经完全适配Java 9+的模块化规则,无需额外添加启动参数。注意升级后原有AnnotationConfiguration已废弃,需要调整HibernateUtil.java的代码,示例如下:
package com.jtcindia.hibernate; import org.hibernate.SessionFactory; import org.hibernate.boot.MetadataSources; import org.hibernate.boot.registry.StandardServiceRegistry; import org.hibernate.boot.registry.StandardServiceRegistryBuilder; public class HibernateUtil { private static final SessionFactory sessionFactory = buildSessionFactory(); private static SessionFactory buildSessionFactory() { try { StandardServiceRegistry standardRegistry = new StandardServiceRegistryBuilder() .configure("hibernate.cfg.xml") .build(); return new MetadataSources(standardRegistry).buildMetadata().buildSessionFactory(); } catch (Exception e) { e.printStackTrace(); throw new ExceptionInInitializerError("SessionFactory初始化失败:" + e.getMessage()); } } public static SessionFactory getSessionFactory() { return sessionFactory; } }
其他问题修复
- 你代码中
HibernateUtil的方法名setSessionFactory是笔误,逻辑是获取SessionFactory,建议改为getSessionFactory,调用处对应调整即可。 - log4j的警告是因为缺少log4j配置文件,在项目的资源目录下新增
log4j.properties文件,添加以下内容即可解决:
log4j.rootLogger=INFO, stdout log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n
内容的提问来源于stack exchange,提问作者Prakash Dash
相关产品推荐
相关产品推荐

