基于Hibernate 5+Spring MVC 5的应用启动报错求助(GlassFish 4.1.1)
这个问题我之前帮同事排查过,核心原因就是JBoss Logging版本冲突——GlassFish 4.1.1自带了一个较低版本的JBoss Logging组件,而Hibernate 5要求更高版本的JBoss Logging(尤其是debugf这个格式化日志方法是高版本才新增的),服务器自带的旧版本先被加载,就会抛出java.lang.NoSuchMethodError。
下面是我亲测有效的解决步骤:
1. 锁定JBoss Logging的版本并清理冲突依赖
首先在你的pom.xml里显式指定兼容Hibernate 5的JBoss Logging版本,比如Hibernate 5.4.x对应的jboss-logging版本是3.4.x系列(比如3.4.3.Final),确保这个版本被优先引入:
<dependency> <groupId>org.jboss.logging</groupId> <artifactId>jboss-logging</artifactId> <version>3.4.3.Final</version> <scope>compile</scope> </dependency>
然后用Maven命令排查依赖树,看看有没有其他依赖偷偷引入了旧版本的JBoss Logging:
mvn dependency:tree | grep jboss-logging
如果输出里有除了你指定版本之外的条目,找到对应的依赖,在pom.xml里排除它的JBoss Logging依赖,比如:
<dependency> <!-- 这里替换成你项目中引入旧版本的依赖 --> <groupId>com.example.some-dependency</groupId> <artifactId>some-artifact</artifactId> <exclusions> <exclusion> <groupId>org.jboss.logging</groupId> <artifactId>jboss-logging</artifactId> </exclusion> </exclusions> </dependency>
2. 调整GlassFish的类加载优先级
GlassFish默认会优先加载自身自带的类库,所以即使你在pom里指定了高版本,服务器还是会先加载旧版本。解决办法是在项目的WEB-INF目录下创建(如果没有的话)glassfish-web.xml,添加类加载器配置:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE glassfish-web-app PUBLIC "-//GlassFish.org//DTD GlassFish Application Server 3.1 Servlet 3.0//EN" "http://glassfish.org/dtds/glassfish-web-app_3_0-1.dtd"> <glassfish-web-app error-url=""> <!-- 设置为false让应用优先加载自身依赖 --> <class-loader delegate="false"/> </glassfish-web-app>
这个配置会让应用自己的类加载器先查找依赖,而不是先委托给服务器的类加载器,这样就能确保我们指定的高版本JBoss Logging被优先使用。
3. 验证Spring MVC和Hibernate的版本兼容性
最后再确认一下Spring MVC 5和Hibernate 5的版本是否匹配,比如Spring 5.2.x搭配Hibernate 5.4.x是经过验证的稳定组合,避免因为框架版本不兼容间接引发依赖问题。
按照这三步操作后,重新打包部署到GlassFish,应该就能解决这个NoSuchMethodError问题了。
内容的提问来源于stack exchange,提问作者Streletz

