Tomcat8中设置类加载优先级优先加载javax.persistence-api-2.2.jar
解决Tomcat 8中javax.persistence.PersistenceContext类加载优先级问题
你遇到的java.lang.NoSuchMethodError问题根源很清晰:Tomcat 8自带的annotations-api.jar中的javax.persistence.PersistenceContext注解缺少synchronization()方法,而你需要的javax.persistence-api-2.2.jar里的该注解包含这个方法,但Tomcat的类加载器默认优先加载了自带的jar。下面是几个可行的解决方案:
方案1:修改Tomcat的类加载顺序(推荐)
Tomcat的Common类加载器默认按文件系统顺序加载TOMCAT_HOME/lib下的jar,我们可以通过修改配置强制指定优先加载javax.persistence-api-2.2.jar:
- 打开
TOMCAT_HOME/conf/catalina.properties文件 - 找到
common.loader配置项,默认内容类似:common.loader=${catalina.base}/lib,${catalina.base}/lib/*.jar,${catalina.home}/lib,${catalina.home}/lib/*.jar - 修改该配置,把
javax.persistence-api-2.2.jar的路径放在最前面,确保它被优先加载:common.loader=${catalina.home}/lib/javax.persistence-api-2.2.jar,${catalina.base}/lib,${catalina.base}/lib/*.jar,${catalina.home}/lib,${catalina.home}/lib/*.jar - 重启Tomcat,此时Common类加载器会先加载
javax.persistence-api-2.2.jar,其中的PersistenceContext类会覆盖annotations-api.jar中的同名类。
方案2:将javax.persistence-api-2.2.jar放入应用的WEB-INF/lib
如果你的应用是独立部署、不需要多个应用共享这个jar,可以直接把javax.persistence-api-2.2.jar打包到应用的WEB-INF/lib目录下。Tomcat的Webapp类加载器遵循先加载自身WEB-INF/lib资源,再委托父类加载器的规则,这样应用会优先使用自己lib中的PersistenceContext类,完全避开Tomcat自带的annotations-api.jar。
为什么Tomcat 9没有这个问题?
Tomcat 9的annotations-api.jar已经移除了javax.persistence相关包,类加载器会直接加载你放入TOMCAT_HOME/lib的javax.persistence-api-2.2.jar中的类,自然不会出现方法缺失的错误。
内容的提问来源于stack exchange,提问作者Pawan Patil
相关产品推荐
相关产品推荐

