同名类冲突-CASE1.两个第三方JAR包中包含同名类


1. 问题描述


项目使用的相关技术栈:Alitomcat+Pandora

日常环境下邮件发送正常,进入预发环境中邮件发送失败。抛出异常(偶现)

java.net.SocketException: Connection reset

    javax.mail.MessagingException: Can't send command to SMTP host;nested exception is:

        java.net.SocketException: Connection closed by remote host

        javamail SSL peer shut down incorrectly

 

2. 排查思路


2.1 邮箱发送源码有BUG

大概网上查了下,该异常的导致原因。没有发现啥问题。朝着邮件发送源码有BUG的方向排查了好久@-@

2.2 环境相关的问题,先看看邮箱相关的JAR包

发现邮箱相关的JAR包有好多个,如下图。再看看抛出异常的类javax.mail.Transport, 同时处在在多个JAR包中。javax.mail\javax.mail-api\mail

 

 

  

 2.3 同名类有多个,两个不同环境,分别从哪个JAR包加载?

对比日常环境、预发环境加载的javax.mail.Transport,发现两个环境加载的包不一样。

 

分析到这里存在以下疑问

  • 如果项目中出现多个全限定名相同的类,从哪个JAR包中加载顺序是怎么样的?
  • 目前项目是Docker化部署的,为啥日常环境、预发环境部署出现不一样? Docker化部署有覆盖不到的场景?

2.4 同名类从哪个JAR包中加载?顺序是怎么样的?

参照StackOverFlow上的一个问答,从/lib目录下,加载JAR包的顺序是什么。某个Tomcat版本巧合之下,加载JAR包是按字母序来的。实际官方指出开发Web应用时,不应该依赖于对JAR包的加载顺序它的排序取决于底层操作系统搜索排序,即  find "/path,"  -name *.jar,find命令返回的顺序是随机的,跟磁盘上文件内容有关系

用提供的静态 class 查找工具findclass.py,在WEB-INF/lib 目录下,查找对应类的JAR包。日常\预发环境找到的包顺序相反。

 

2.5 Docker化部署前提下,为什么会出现部署不一致情况?

环境是一致的,但是实际应用时,还是可能会有细节上的不同。 

 

3. 总结


  • 不要引入非必要的JAR包,明确功能,然后引入
  • 可以认为加载的类时,选用该类所在的JAR是无序的(取决于find命令返回顺序)。官方指出不应对JAR包加载顺序有依赖。
  • Docker化部署理论上是环境一致的,但实际应用时,可能还是会存在细节上有不一样,比如find命令返回顺序不同。

 

 

参考链接:

https://bz.apache.org/bugzilla/show_bug.cgi?id=57129


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM