多个版本的javamail jar导致NoSuchProviderException [英] multiple versions of javamail jar causing NoSuchProviderException

查看:85
本文介绍了多个版本的javamail jar导致NoSuchProviderException的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个独立的库(jar文件),已将其添加到应用程序服务器类路径中,以监视JVM中所有正在运行的应用程序,并在发生某些问题时发送电子邮件.

I have a standalone library ( jar file) that is added to the application server classpath to monitor all the running applications in the JVM and send email when some issue happens.

jar文件将所有依赖项捆绑在jar中(使用maven-shade-plugin),包括javamail jar文件.

the jar file have all the dependencies bundled in the jar (using the maven-shade-plugin) including the javamail jar file.

当应用服务器中的其他Web应用程序之一将javamail作为依赖项时,我的jar文件中的javamail发生了一些依赖项冲突,我得到了一个异常

When one of the other webapplications in the appserver have javamail as a dependency, some dependency conflict happens with the javamail in my jar file and I get an exception

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

我无法修改正在运行的应用程序,该如何解决此冲突.我只能控制我的jar文件.

How can I solve this conflict knowing that I can't modify the running appplications. I only have control over my jar file.

修改:

我通过javamail API进行了调试.并且我发现javax.mail.Session使用反射构造了一个类型为com.sun.mail.smtp.SMTPTransport的新对象,并将两个参数传递给构造函数,而不是使用它试图在同一jar文件中的SMTPTransport从已部署应用程序之一中的另一个mail.jar使用SMTPTransport.

I debugged through the javamail API. and I found out that the javax.mail.Session construct a new object of type com.sun.mail.smtp.SMTPTransport using reflection and pass two parameters to the constructor, but rather than using SMTPTransport located in the same jar file it tries to use SMTPTransport from the other mail.jar located in one of the deployed apps.

推荐答案

在tomcat 7中,默认情况下, Web应用程序将首先查找以下顺序的类:

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

  1. 首先关注WEB-INF/classes
  2. 然后将其放入WEB-INF/lib中的jars
  3. ,如果仅未找到该类,则在YOUR_SERVER_HOME/lib
  4. 然后在系统类加载器上进行操作,如此处
  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

其他WAR的类版本(在类/WEB-INF/lib上)无法从另一个WAR内部看到.

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?

如何将独立库添加到服务器类路径?它是复制到YOUR_SERVER_HOME/lib上,还是通过catalina.properties的shared.loader或common.loader属性添加到服务器类路径的文件夹

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

是每个WAR应用程序在WEB-INF/lib上提供其自己的邮件罐,还是作为JNDI资源在服务器级发布的库,例如上述

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

服务器中的任何应用程序是否未在我上面提到的默认类加载模式下运行,并且正在使用委托= true(这意味着它将首先在服务器上查看,然后才在WAR上查看)? 此处是配置方式,请检查Resource元素在context.xml或server.xml

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. 按照此处部分中的安装说明,将JavaMail作为JNDI资源安装在tomcat 7上. JavaMail库.让所有应用程序都像tomcat docs中一样使用JNDI资源,并使用阴凉插件排除功能从独立库中删除Java邮件.这将始终有效,并且是最推荐的解决方案.

  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.

如果您使用的是Java 7,请尝试使用 JHades 对不同应用程序的类路径进行故障排除.您可以对WAR进行重复类的静态分析,或者查看给定类在运行时使用的版本以及可用的其他版本.

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.

由于无法控制其他应用程序的部署设置或其内容,JNDI的使用等,因此可以肯定地在所有环境中使用任何应用程序的解决方案是重构该工具,因此它不需要在服务器上安装mail.jar.该工具可以将电子邮件请求写入例如文件或数据库表,并且部署在服务器上的另一个WAR将轮询表文件并发送邮件.或称为bash/bat脚本,其本身会在单独的Java进程中发送电子邮件.

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.

诸如Dynatrace之类的性能分析工具基于JVM代理,并使用类似的机制,不需要在服务器级别引入库,该代理收集数据并将其发送到收集过程中,该过程将其存储在某个地方以供进一步使用analisys ,例如通过电子邮件发送警报等处理方法.

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.

希望这会有所帮助,通常我看不到将库部署到EE服务器的任何方法,并且请确保它们永远不会对不同服务器类型和不同应用程序类加载设置上的任何应用程序造成问题.

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.

最好的办法是使用该工具,以便它至少依赖于服务器上部署的库,将其分解为单独的模块,而仅在服务器上运行收集模块,或者研究诸如Dynatrace之类的替代方案.

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.

这篇关于多个版本的javamail jar导致NoSuchProviderException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆