jar冲突问题与Tomcat 加载jar的顺序

49 篇文章 6 订阅
19 篇文章 0 订阅

前言

笔者在解决业务问题的时候,很多业务提出了为啥我的服务在测试环境啥问题都没有,发布生产就出问题了,第一反应是配置不一样😅?实际上部分原因可能还与发布的容器有关,比如Tomcat8,比如jar冲突。刚好解决了jar冲突的事情,总结分析原因。

1. tomcat源码下载

Tomcat的新版本是可以直接下载源码的,但是Tomcat7就只能

Index of /dist/tomcat (apache.org)

记得下载src

2. tomcat 7与tomcat 8的区别

以非嵌入式tomcat 7 8 为例

2.1 Tomcat7

tomcat加载WEB-INF/lib是在org.apache.catalina.loader.WebappLoader加载的

 可以看到加载是通过

DirContext

实现的,这个在tomcat有2种方式WAR、File

Tomcat通过解压运行,加载默认通过File,会把lib下得jar按照字母排序,加载jar的顺序固定,所有环境一样,要么都冲突,要么都正常,环境验证好就不存在类冲突问题。

2.2 tomcat 8

 tomcat8的设计有些不同,代码重构了,在org.apache.catalina.loader.WebappClassLoaderBase下的start

 

可以看到

 进一步继续,直接file.list获取过滤jar,并没有排序

 以macOS为例

 直接查看jdk源码

初步看扫描的代码,大致是顺序与服务器的信息有关,导致Tomcat8在不同服务器WEB-INF/lib的jar的顺序不一样,加载的类如果有冲突会不一样。 

3. 为什么相同的war,不同机器有的冲突有的没有

实际上Tomcat7是不存在问题的,Tomcat8就会出现类冲突的情况,本质还是Tomcat8暴露了类冲突的情况,并不是Tomcat7解决问题,而是隐藏了问题。

解决类冲突还是需要静态扫描,人工比对处理(排jar),扫描也很好写,包与类路径一样即为可能冲突类

spring boot又是怎么处理的呢,通过jarFile的迭代器迭代的,所以是顺序的,并且jar启动的的jar的BOOT-INF/lib也是不会顺序变换的

总结

仅仅是Tomcat使用读取文件的方式启动就会根不同机器的环境相关,顺序不一致而出现类冲突的暴露问题,说明了不同环境问题出现的原因也会跟执行容器相关。这可能也是spring boot发展的一个原因。当然Tomcat也可以war读取,不解压运行,就不会有这个问题了,只是不知道什么原因不常用。

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值