Spring 5.1.3与Tomcat 9集成邮件功能报NoSuchMethodError问题咨询
问题根因
你遇到的NoSuchMethodError是典型的依赖版本冲突问题:
- 当前pom.xml中javax.mail相关依赖的scope设为了
provided,代表项目打包时不会包含这两个依赖,运行时直接使用Tomcat容器提供的依赖包 - Tomcat默认遵循双亲委派类加载机制,会优先加载
CATALINA_HOME/lib下的依赖,再加载应用WEB-INF/lib下的依赖,所以即使你把高版本包放到应用lib目录下也不会生效 - 你当前使用的javax.mail-api 1.6.2版本调用的
LineOutputStream构造方法在Tomcat内置的mail-1.4.7.jar中不存在,因此抛出方法不存在异常
解决方案(无需修改Tomcat内置依赖)
方案1:配置Tomcat应用级类加载优先级(推荐)
在你的Web应用的src/main/webapp/META-INF目录下新建context.xml文件,添加如下配置:
<?xml version="1.0" encoding="UTF-8"?> <Context> <!-- 配置优先加载应用自身的依赖包,优先级高于Tomcat共享lib --> <Loader delegate="false"/> </Context>
这个配置只会对当前应用生效,让当前应用的类加载器优先加载自己WEB-INF/lib下的依赖,只有加载不到的类才会委托给父类加载器(Tomcat公共类加载器)加载,完全不需要修改Tomcat全局配置。
方案2:调整pom.xml依赖配置
修改pom.xml中mail相关依赖的配置:
- 删除原有scope为
provided的两个mail相关依赖 - 添加高版本的完整mail实现依赖,scope保留默认的
compile,这样打包时会把高版本mail包打到应用的WEB-INF/lib下:
<dependency> <groupId>com.sun.mail</groupId> <artifactId>javax.mail</artifactId> <version>1.6.2</version> </dependency>
这个包是官方完整实现包,同时包含API和实现类,不会出现接口和实现版本不匹配的问题。
兜底方案:对齐API和实现版本
如果你不想修改类加载配置,也可以把javax.mail-api的版本降到1.4.7,和Tomcat内置的实现版本完全对齐,就不会出现方法不存在的问题:
<dependency> <groupId>javax.mail</groupId> <artifactId>javax.mail-api</artifactId> <version>1.4.7</version> <scope>provided</scope> </dependency>
修改完成后重新打包应用部署,即可正常发送邮件,不会再抛出NoSuchMethodError异常。
内容的提问来源于stack exchange,提问作者armada1750
相关产品推荐
相关产品推荐

