TomEE Plus 9.1 - Jakarta EE Platform Maven Project - How to exclude geronimo-mail jar

117 Views Asked by At

I have an Email class that uses the following imports:

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;

This class is built and tested in a package in a different project that I use to build and maintain utility classes. The package is then exported in a jar for use in other projects. The project in which the exported package is used is a web project running in TomEE 9.1 Plus.

Both the project where the class is built and the TomEE web project where the class is used, use the same maven dependencies [below].

<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>

Unit tests of the Email class correctly perform constructing and sending MimeMessages with all options like attachments functioning as expected.

The problem is when the Email class is used in the web project. It is not a compile or runtime exception. The methods in the exported class are executed without error in the web project. However, when the methods are executed in the web project, TomEE points to a jar geronimo-mail_2.1_spec-1.0.0-M1.jar that contains implementations of the jakarta.mail.internet.* classes.

jakarta.mail.internet.MimeBodyPart.class from the geronimo jar, uses a DataHandler object that builds a MimeMessage in which the email body has no content. When the email is received, the body is blank.

Is there a way to prevent Tomcat from using the geronimo-mail jar? I've tried excluding the jar without success by doing the following:

<dependency>
    <groupId>jakarta.activation</groupId>
    <artifactId>jakarta.activation-api</artifactId>
    <version>2.1.2</version>
    <exclusions>
        <exclusion>
            <groupId>org.apache.geronimo.mail</groupId>
            <artifactId>geronimo-mail_2.1_mail</artifactId>             
        </exclusion>
        <exclusion>
            <groupId>org.apache.geronimo.specs</groupId>
            <artifactId>geronimo-activation_2.0_spec</artifactId>
        </exclusion>
        <exclusion>
            <groupId>org.apache.geronimo.mail</groupId>
            <artifactId>geronimo-mail_2.1_provider</artifactId>
        </exclusion>
        <exclusion>
            <groupId>org.apache.geronimo.specs</groupId>
            <artifactId>geronimo-mail_2.1_spec</artifactId>             
        </exclusion>
    </exclusions>
</dependency>

and including the jar as a dependency, then setting the scope as 'provided'.

<dependency>
    <groupId>org.apache.geronimo.specs</groupId>
    <artifactId>geronimo-mail_2.1_spec</artifactId>
    <version>1.0.0-M1</version>
        <scope>provided</scope>
</dependency>

I also tried putting the jakarta and angus-mail jars directly in WEB-INF/lib folder of the web project.

I also tried using Eclipse's "Configure Build Path", browsing to the Tomcat v10.0 runtime, locating the geronimo-mail spec and provider jars, and entering exclusion patterns of **/*.class.

All with no success. The Email class in the TomEE project still uses classes from the geronimo-mail jar.

Any suggestion how to force Tomcat to open the correct jar containing the correct jakarta.mail implementations from the maven dependencies?

Thank you

2

There are 2 best solutions below

0
Eric On BEST ANSWER

Had the same issue on this one... We're using "SimpleJavaMail" which has an Email dependency that was overridden via geronimo at runtime (specifically when including INLINE embedded images).

Simple solution was to just wack the jar(s) related to geronimo mail in TomEE lib directory. SimpleJavaMail will bring along Activation & Jakarta Mail implementations. *** Probably not the most elegant solution, but it's just email. https://www.simplejavamail.org/

Digging into the overlap on implementation MimeMessage/DataHandler wasn't worth the time.

0
Kekzpanda On

The answer of Eric is already the best solutions, but I would like elaborate on the reasons and add same Gradle info.

Your build tool has no influence on what your runtime environment provides in addition to the libraries or classes you package. You can exclude from your available sources, but deletions past packaging are out of the hands of your build.

If your runtime container comes with additional libraries, like the lib folder of the TomEE installation, then you have to make sure these are removed before deployment of the container, i.e. before starting the TomEE. TomEE packages come with a set of libraries, that are assumed to be needed by your application, but it is your duty to make sure there is no extra clutter in this.

The removal of the libraries has to be done in all environments, also locally. Do not forget to add documentation or automation for this for other developers that will work on your project.

Additionally, it is still necessary to exclude the libraries at test and compilation time using your build tool - as the OP did. Otherwise your test cases run against different code then your production environment.

For the Gradle users among us, the exclusions for TomEE 9.1.1 are like this:

implementation ("org.apache.tomee:jakartaee-api:9.1.1") {
    exclude(group: "org.apache.geronimo.javamail", module: "geronimo-javamail_1.4_mail")
    exclude(group: "org.apache.geronimo.mail", module: "geronimo-mail_2.1_provider")
    exclude(group: "org.apache.geronimo.specs", module: "geronimo-activation_2.0_spec")
    exclude(group: "org.apache.geronimo.specs", module: "geronimo-mail_2.1_spec")
}

The geronimo mail dependencies are also transitively included via (at least) these packages:

  • org.apache.tomee:cxf-shade:9.1.0
  • org.apache.tomee:cxf-rt-rs-mp-client-shade:9.1.0
  • org.apache.tomee:openejb-core:9.1.1

Do the same exclusions as above for these, if you have them among your dependencies. (Pay attention that in TomEE 9.1.1, the cxf-packages still carry 9.1.0 as a version)