Jetty.project: Upgrade javax.mail to latest version

Created on 6 Jun 2017  路  13Comments  路  Source: eclipse/jetty.project

As reported in jetty-users ...

http://dev.eclipse.org/mhonarc/lists/jetty-users/msg07816.html

The javax.mail that we ship is apparently old, and we should upgrade our version.

Documentation

Most helpful comment

It isn't going to be possible to upgrade the javax.mail api jar unfortunately. The javax.mail-api jar in more recent revs is a complete mess. As an API jar it is useless because it depends on the com.sun.mail implementation jar. It doesn't even depend on it in a straightforward dependency, but rather uses some direct configuration of the maven-dependency-plugin in its pom to download and unpack the com.sun.mail impl jar during its compilation phase so there are no traces of a dependency, but the moment you try and use the api jar it will crash out complaining about lack of a com.sun.mail impl.

So, the solution that I will adopt is that as of jetty-10, we will no longer distribute a javax.mail api jar in $jetty.home/lib/jndi. We will keep the jetty MailSessionReference as documented here: https://www.eclipse.org/jetty/documentation/9.4.6.v20170531/jndi-configuration.html#configuring-mail-with-jndi, but if you want to use that feature, you will have to provide javax.mail api and impl jars of your choice.

All 13 comments

It isn't going to be possible to upgrade the javax.mail api jar unfortunately. The javax.mail-api jar in more recent revs is a complete mess. As an API jar it is useless because it depends on the com.sun.mail implementation jar. It doesn't even depend on it in a straightforward dependency, but rather uses some direct configuration of the maven-dependency-plugin in its pom to download and unpack the com.sun.mail impl jar during its compilation phase so there are no traces of a dependency, but the moment you try and use the api jar it will crash out complaining about lack of a com.sun.mail impl.

So, the solution that I will adopt is that as of jetty-10, we will no longer distribute a javax.mail api jar in $jetty.home/lib/jndi. We will keep the jetty MailSessionReference as documented here: https://www.eclipse.org/jetty/documentation/9.4.6.v20170531/jndi-configuration.html#configuring-mail-with-jndi, but if you want to use that feature, you will have to provide javax.mail api and impl jars of your choice.

Thanks Jan, I will ask to Bill Shannon, the primary developer and maintainer of the JavaMail API at Oracle. to come here to try to resolve issue with you.

You don't need, and should not include, the javax.mail-api jar file. The only purpose of that jar file is to allow you to compile programs against the pure JavaMail API.

All you need is the javax.mail jar file, which includes the entire JavaMail API and implementation.

@bshannon we've worked out that is what is intended with this structure, but it really is sub optimal.

We'd like to be able to declare our dependency on a particular version of javax.mail API, but not depend on a specific implementation. Yet we need an implementation for testing, so maven ends up giving us two copies of the API. Similarly any user of jetty will have the same problem if they use an implementation that also embeds the API.

The only solution is for us to depend on the implementation as a provided dependency, so that we can both compile and test against it, but distribute neither the API nor implementation. This works, but it means that we effectively no longer have a runtime dependency on a particular version of the API - probably not a problem for a moderately stable API like mail, but a problem in general as a pattern.

Furthermore, the approach of embedding the API in the impl jar kind of breaks the whole ServiceLoader mechanism. In order to do ServiceLoader.load<javax.some.Api> I need to have the API on my classpath to be able to discover the implementation(s) in other jars. But with the javax.mail approach there is no independent API jar that can be used to load a service and it would be impossible to have multiple implementation. Not a problem for mail, which doesn't use the service loader, but a problem in general.

Anyway, I guess we are not going to change your mind on this, as I think you've been embedding APIs in impls for some time. Still makes no sense to us, but we'll work around it.

This isn't the place to debate the merits of the JavaMail API design, which was created 20 years ago. If you want a different implementation of the JavaMail API from a different vendor, you need a different Maven artifact. There's no implementation of an API layer that everyone is required to use that then delegates to different implementations. The API is defined by the API signatures, not the classes that declare those APIs. Different vendors can declare the same APIs and be compatible.

It sounds like you want to be able to express a dependency on version X of the JavaMail API, and get some implementation of version X without specifying a dependency on which version of which implementation you get. I don't know how to do that in Maven.

If you only want to compile against the API, and depend on the implementation being supplied at runtime via some other mechanism, the javax.mail-api jar is what you want. Depending on how the implementation is supplied at runtime, there are different ways to declare what version of the API must be supplied. OSGi has one way of doing this, for example.

@bshannon the confusion comes into place when you note that the vast majority of other javax-*-api artifacts limit their included classes to just the API classes, no implementation (that's a different jar).

I understand there's confusion. People are clearly making assumptions that were not intended. JavaMail follows the pattern of the JDK classes, which was the dominant pattern at the time.

In jetty-10 we have removed javax.mail and javax.transaction from the distribution. If you require these jars you will need to download them and place them in your $jetty.base/lib/ext directory (after enabling the 'ext' module), or making your own module to download and place them onto the container classpath.

@janbartel @WalkerWatch i think this issue just became a Documentation issue.

@joakime right you are: assigning to @WalkerWatch .

I will include this in the 9.x -> 10.x upgrade/transition guide when the time comes.

Im using Java8, I receve a Method not found when parsing the Message intervace with IMAPMessage, the method was
(javax.mail.internet.ParameterList.combineSegments())
Wich best way to Load Message from my package javax.mail-1.5.2.jar? I try in jetty-web.xml, and that not working... :( ->Thats with a Docker image FROM jetty:9.4-jre8

Ok, Ok, I did as at: https://www.eclipse.org/lists/jetty-users/msg07816.html
put:
<Call name="prependSystemClass"> <Arg>-javax.mail.</Arg> </Call> <Call name="prependServerClass"> <Arg>javax.mail.</Arg> </Call>
On my WEB-INF/jetty-web.xml
And now , that just working!!! thanks @janbartel !!

Was this page helpful?
0 / 5 - 0 ratings