struts2 升级 获取 file_玩大发了,Tomcat 8.5 升级有坑…

在将系统从Tomcat8.5.x + JDK1.8.x升级后,出现NoSuchMethodError异常,导致系统无法启动。问题源于jar包冲突,由于Tomcat8之后的jar加载顺序不再按字母排序,而是由File.listFiles()决定,这可能导致不同环境加载顺序不一致。解决方法包括排除冲突依赖、降级Tomcat或自定义类加载器。通过排查,发现并解决了冲突的jar包,系统恢复正常。
摘要由CSDN通过智能技术生成

最近某全系统做了环境升级:

  • Tomcat 8.5.x
  • JDK 1.8.x

有个系统升级后出现没有这个方法异常:

threw exception; nested exception is java.lang.NoSuchMethodError:......

上线后系统起不来,这下玩大了。。。

咋一看应该是 jar 包冲突了,经过排查,果然是 jar 包冲突了,类路径下存在了几个不同版本类似的 jar 包,是由另外一个依赖引入进来的 compile 依赖,然后排除冲突的依赖就解决了。

那么问题来了,既然 jar 包冲突,相同的环境,为什么在开发环境、测试环境、预上线环境都没有出现问题?

经过查证,那是因为 Tomcat 8 之后的 jar 包加载方式变了,8 之前是按照字母顺序加载的,而 8 之后就变了,Tomcat 使用的是 File.listFiles() 方法来获取目前下的 jar 包,加载的顺序就和文件系统返回的顺序有关,就不一定是按字母排序了。

java.io.File#listFiles() 源码注释:

a3583acc1ecff5282833ee800d3bcecf.png

这个方法是获取目前下的所有文件,它不能保证按指定的顺序返回结果,特别是,不能保证按字母顺序返回。为什么本地环境可以,可能是刚好是按字母排序的了。

那么,这个问题的解决办法可以是:

1)如果是冲突问题,排除冲突依赖解决 jar 包冲突或者降级到 tomcat 7 就行了,又或者是写个脚本检查一下包名是否有重复的包;我们刚好是有两个 jar 包冲突了,解决冲突就正常了;

2)如果是业务问题,我们都知道 JVM 双亲委派机制,同一个类是不能重复加载的,如果业务确实需要加载多个版本的依赖,那就需要实现自己的自定义类加载器分别去加载对应的 jar 包;

关于类加载器、双亲委派机制都可以点击下面的了解更多链接关注Java技术栈往期文章找到相对应的解答。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值