zoukankan      html  css  js  c++  java
  • 玩大发了,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() 源码注释:

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

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

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

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

    关于类加载器、双亲委派机制都可以在Java技术栈公众号往期文章找到相对应的解答。

    关注公众号Java技术栈回复"面试"获取我整理的2020最全面试题及答案。

    推荐去我的博客阅读更多:

    1.Java JVM、集合、多线程、新特性系列教程

    2.Spring MVC、Spring Boot、Spring Cloud 系列教程

    3.Maven、Git、Eclipse、Intellij IDEA 系列工具教程

    4.Java、后端、架构、阿里巴巴等大厂最新面试题

    觉得不错,别忘了点赞+转发哦!

  • 相关阅读:
    第二阶段:团队开发Fooks第七天
    第二阶段:团队开发Fooks第六天
    第二阶段:团队开发Fooks第五天
    【POI每日题解 #9】SKA-Piggy Banks
    ac自动机
    【POI每日题解 #8】DYN-Dynamite
    vector
    【POI每日题解 #7】TES-Intelligence Test
    【POI每日题解 #6】KRA-The Disks
    DP
  • 原文地址:https://www.cnblogs.com/javastack/p/13186039.html
Copyright © 2011-2022 走看看