玩大发了,Tomcat 8.5 升级有坑…

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

  • 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() 源码注释:

玩大发了,Tomcat 8.5 升级有坑…_第1张图片

 

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

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

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

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

学习Java不仅依靠自身的努力,更要站在巨人的肩膀上,学习一些开源的源码的同时更应该多看看技术文档以及极技术视频;

正是由于前辈们的无私奉献和分享精神以及源源不断的技术开源才使得我们这些后浪轻易的获取更多优秀的学习资源,使得互联网行业迅速发展;这里,我也要做一个无私奉献的小程序员,我要做一个资源的传播者

你可能感兴趣的:(玩大发了,Tomcat 8.5 升级有坑…)