zoukankan      html  css  js  c++  java
  • 曹工杂谈:用好verbose,Jar包冲突不再难

    Jar包冲突的相关文章:

    了不得,我可能发现了Jar 包冲突的秘密

    一、前言

    jar包冲突分多种,简单理解来说,就是同package且同名的类在多个jar包内出现,如果两个jar包在同一个classloader下,那么最终的结果是,只会加载其中的一个。

    有时,这个错误一般在运行时出现,报的错可能是,找不到某方法,或者呢,更隐蔽的,不会报错,但是逻辑不对。

    针对运行中的应用,可以考虑使用阿里出品的arthas来处理。

     

    我今天呢,只是简单的找不到方法的情况,所以不需要用到那个。 我这里的场景是,在学习rocketMq的过程中,其依赖的jar包如下:

    <dependency>
       <groupId>org.apache.rocketmq</groupId>
       <artifactId>rocketmq-client</artifactId>
       <version>4.3.0</version>
    </dependency>

    该jar包间接依赖如下:

     

    上图是截的idea插件,maven helper。但是一开始并没想起来去看这里。

     

    为什么会冲突呢,因为我把测试类写在了一个使用了netty 5 版本的工程里。(为了偷懒。。)

    二、解决冲突的方式一

    我这里报错如下:

    1 Exception in thread "main" java.lang.NoSuchMethodError: io.netty.bootstrap.Bootstrap.channel(Ljava/lang/Class;)Lio/netty/bootstrap/AbstractBootstrap;
    2     at org.apache.rocketmq.remoting.netty.NettyRemotingClient.start(NettyRemotingClient.java:165)
    3     at org.apache.rocketmq.client.impl.MQClientAPIImpl.start(MQClientAPIImpl.java:225)
    4     at org.apache.rocketmq.client.impl.factory.MQClientInstance.start(MQClientInstance.java:234)
    5     at org.apache.rocketmq.client.impl.producer.DefaultMQProducerImpl.start(DefaultMQProducerImpl.java:171)
    6     at org.apache.rocketmq.client.impl.producer.DefaultMQProducerImpl.start(DefaultMQProducerImpl.java:144)
    7     at org.apache.rocketmq.client.producer.DefaultMQProducer.start(DefaultMQProducer.java:172)
    8     at rocketmq.TestRocketMq$SyncProducer.main(TestRocketMq.java:21)

     

    上面意思就是,io/netty/bootstrap/AbstractBootstrap 不存在 channel(Ljava/lang/Class;) 这个方法。

     

    我在ide里,打开了netty 5 jar包里的这个类,确实没找到这个方法,估计就是这个原因了。

    怎么验证程序加载了这个类呢?直接在启动参数里,加入 -verbose:class ,然后重新启动,过程中会打印出加载的class:

     

     

    上图可以看到,果然是从5.0版本的netty里加载的。

    三、解决jar包冲突的方式2

    idea里安装maven helper插件,然后选择pom,下图即可看出冲突的jar包:

    但是,说实话,这个一般事先并不会去看,很有可能都是事后出问题才去这里看。

    四、总结

    今天这个场景很简单,文章开头那个链接里的案例要复杂一点(windows上可以,linux不行)。大家也可以看下。

    jar包为什么冲突?这里再理解下,因为在jvm里,一个类是唯一的,说明类加载器相同 + 类的全路径名相同。

    如果同一个类加载器下出现了两个全路径相同的类,自然就冲突了。

  • 相关阅读:
    Eclipse 远程调试
    大数据处理方法bloom filter
    sicily 1259 Sum of Consecutive Primes
    sicily 1240. Faulty Odometer
    sicily 1152 简单马周游 深度优先搜索及回溯算法
    sicily 1050 深度优先搜索解题
    sicily 1024 邻接矩阵与深度优先搜索解题
    sicily 1156 二叉树的遍历 前序遍历,递归,集合操作
    sicily 1443 队列基本操作
    sicily 1006 team rankings 枚举解题
  • 原文地址:https://www.cnblogs.com/grey-wolf/p/11403444.html
Copyright © 2011-2022 走看看