TomEE Plus 9.1 Maven项目:如何排除geronimo-mail jar包?
我开发了一个Email工具类,使用Jakarta Mail相关API,导入代码如下:
import jakarta.activation.DataHandler; import jakarta.activation.DataSource; import jakarta.activation.FileDataSource; import jakarta.faces.context.FacesContext; import jakarta.mail.BodyPart; import jakarta.mail.Message; import jakarta.mail.MessagingException; import jakarta.mail.Multipart; import jakarta.mail.PasswordAuthentication; import jakarta.mail.Session; import jakarta.mail.Transport; import jakarta.mail.internet.AddressException; import jakarta.mail.internet.InternetAddress; import jakarta.mail.internet.MimeBodyPart; import jakarta.mail.internet.MimeMessage; import jakarta.mail.internet.MimeMultipart;
工具类项目和部署用的Web项目使用相同的Maven依赖:
<dependency> <groupId>jakarta.platform</groupId> <artifactId>jakarta.jakartaee-api</artifactId> <version>9.1.0</version> </dependency> <dependency> <groupId>jakarta.mail</groupId> <artifactId>jakarta.mail-api</artifactId> <version>2.1.2</version> </dependency> <dependency> <groupId>org.eclipse.angus</groupId> <artifactId>angus-mail</artifactId> <version>2.0.1</version> </dependency> <dependency> <groupId>jakarta.activation</groupId> <artifactId>jakarta.activation-api</artifactId> <version>2.1.2</version> </dependency>
工具类单元测试正常,但部署到TomEE 9.1 Plus的Web项目时,容器加载了geronimo-mail_2.1_spec-1.0.0-M1.jar中的类,导致邮件内容为空,尝试多种依赖排除无效,需要强制让容器使用Maven依赖中的Angus Mail实现。
解决方案
1. 在Web项目pom.xml中排除TomEE自带的Geronimo Mail依赖
如果Web项目依赖TomEE相关包,直接在依赖中排除Geronimo的mail spec和实现,同时确保Angus Mail被打包到WEB-INF/lib:
<!-- 示例:排除TomEE依赖中的Geronimo Mail包 --> <dependency> <groupId>org.apache.tomee</groupId> <artifactId>tomee-embedded</artifactId> <version>9.1.0</version> <scope>provided</scope> <exclusions> <exclusion> <groupId>org.apache.geronimo.specs</groupId> <artifactId>geronimo-mail_2.1_spec</artifactId> </exclusion> <exclusion> <groupId>org.apache.geronimo.mail</groupId> <artifactId>geronimo-mail</artifactId> </exclusion> </exclusions> </dependency> <!-- 强制Angus Mail编译并打包到war中 --> <dependency> <groupId>org.eclipse.angus</groupId> <artifactId>angus-mail</artifactId> <version>2.0.1</version> <scope>compile</scope> </dependency>
2. 配置TomEE系统类加载器排除规则
在TomEE的conf/system.properties文件,或者Web项目的WEB-INF/classes/system.properties中添加以下配置,让系统类加载器跳过Geronimo的mail相关类,优先加载Web应用自身lib中的实现:
openejb.system.classloader.excludes=org.apache.geronimo.mail.,jakarta.mail. openejb.system.classloader.include=
3. 使用jboss-deployment-structure.xml指定加载优先级
在Web项目的WEB-INF目录下创建jboss-deployment-structure.xml文件,明确排除TomEE自带的Mail模块,使用自身依赖:
<jboss-deployment-structure> <deployment> <exclusions> <module name="org.apache.geronimo.specs.geronimo-mail_2.1_spec"/> <module name="org.apache.geronimo.mail.geronimo-mail"/> </exclusions> <dependencies> <module name="deployment.classpath" export="true"/> </dependencies> </deployment> </jboss-deployment-structure>
4. 手动替换TomEE自带的Mail包
如果上述配置都无效,可直接替换TomEE全局lib中的包:
- 删除TomEE安装目录
lib下的geronimo-mail_2.1_spec-*.jar和geronimo-mail-*.jar - 将
angus-mail-2.0.1.jar、jakarta.mail-api-2.1.2.jar、jakarta.activation-api-2.1.2.jar复制到lib目录
注意:此方法会影响该TomEE实例上的所有应用,需谨慎操作。
验证配置是否生效
在Email工具类中添加以下代码,打印当前MimeMessage类的加载来源,确认是否使用了Angus Mail:
MimeMessage msg = new MimeMessage(session); System.out.println("MimeMessage类加载器: " + msg.getClass().getClassLoader()); System.out.println("MimeMessage类来源: " + msg.getClass().getProtectionDomain().getCodeSource().getLocation());
若输出显示来自WEB-INF/lib/angus-mail-2.0.1.jar或TomEE lib目录下的Angus包,说明配置生效。
内容的提问来源于stack exchange,提问作者Ted Spradley

