JavaMail的罐子的多个版本造成​​NoSuchProviderException(multip

2019-10-18 22:21发布

我有一个添加到应用程序服务器类路径中独立的库(jar文件)来监视JVM运行所有的应用程序和当一些问题发生发送电子邮件。

jar文件都包括了JavaMail jar文件中的jar(使用maven的遮阳帘插件)捆绑所有的依赖。

当应用程序服务器的其他web应用的一个有作为的JavaMail依赖,一些依赖冲突发生在我的jar文件了JavaMail,我得到一个异常

MessagingException :javax.mail.NoSuchProviderException: No provider for smtp 

我该如何解决这个矛盾知道,我不能修改正在运行的appplications。 我只有在我的jar文件控制。

编辑

我通过了JavaMail API调试。 我发现该javax.mail.Session使用反射构造型com.sun.mail.smtp.SMTPTransport的一个新对象,并通过两个参数来构造,但不是使用位于同一罐SMTPTransport文件,它试图使用SMTPTransport从位于部署的应用程序之一,其他的mail.jar。

Answer 1:

In tomcat 7, by default web applications will look first for classes on this order:

  1. first on WEB-INF/classes
  2. then inside jars in WEB-INF/lib
  3. and if the class was not found only then in YOUR_SERVER_HOME/lib
  4. Then on the system classloaders, as described here

Class versions from other WARs (on classes / WEB-INF/lib) cannot be visible from inside another WAR.

Can you let us know of further info that could help track down the problem:

  • what does the standalone library do in more detail, how does it monitor the other applications?

  • how is the standalone library added to the server classpath? Is it copied on YOUR_SERVER_HOME/lib, or is a folder added to the server classpath via shared.loader or common.loader properties of catalina.properties

  • does each WAR application provide it's own mail jars on WEB-INF/lib, or is the library published at the server level as a JNDI resource such as mentioned here on section Install the JavaMail libraries

  • Is any of the applications in the server NOT running in the default classloading mode that I mentioned above, and is using delegate = true (meaning it will look on the server first and only then on the WAR) ? here is how this would be configured, check for a Resource element in the context.xml or server.xml

Some suggestions for possible solutions:

  1. Install JavaMail on tomcat 7 as a JNDI resource following the installation instructions here on section Install the JavaMail libraries. Have all applications use the JNDI resource as in the tomcat docs, and remove java mail from the standalone library using a shade plugin exclusion. This will always work and it's the most recommended solution.

  2. If you are using Java 7, try to use JHades to troubleshoot the classpath of the different applications. You can do static analysis on the WARs for duplicate classes, or view what are the versions used at runtime of a given class, and which other versions are available.

  3. Since there is no control over the deployment settings of the other applications or their contents, use of JNDI, etc., a solution that will work for sure in all environments and with any application is to refactor the tool so that it does not require mail.jar to be installed on the server. The tool can write an email request to for example a file or a database table, and another WAR deployed on the server would poll the table file and send the mail. Or a bash/bat script is called that itself sends the email on a separate java process.

Performance analysis tools such as Dynatrace are based on JVM agents and use a similar mechanism that does not need the introduction of libraries at the server level, the agent collects data and sends it to a collecting process that stores it somewhere for further analisys, treatment such as send alarms via emails, etc.

Hope this helps, in general I don't see any way to deploy libraries to a EE server and be sure that they will never cause problems to any application on different server types and different application classloading settings.

The best is probably adapt the tool so that it relies on a minimum of libraries deployed on the server, breaking it up into separate modules with only the collecting module running on the server or look into alternatives such as Dynatrace.



Answer 2:

我不熟悉的行家遮阳帘插件。 是否打包在一个新的jar文件中的原始jar文件? 是否提取原始jar文件的内容和内容插入到新的jar文件? 如果是后者,它可能只包括类文件,而不是在META-INF是配置了JavaMail提供商的资源文件。

当然,最好的办法是为被包含在服务器的类路径只有一个JavaMail的jar文件拷贝安排。



Answer 3:

升级包含在Tomcat 7的JavaMail到1.5.3版本的JavaMail包含了修复的Bug 6668 -skip无法使用存储和运输类 。 您可以下载从最新的快照和官方版本的JavaMail参考实现的主页。



文章来源: multiple versions of javamail jar causing NoSuchProviderException