曹工杂谈:用好verbose,Jar包冲突再也不难

Jar包冲突的相关文章:html

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

1、前言

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

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

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

 

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

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

该jar包间接依赖以下:jvm

 

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

 

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

 

2、解决冲突的方式一

我这里报错以下:post

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里加载的。

 

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

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

 

可是,说实话,这个通常事先并不会去看,颇有可能都是过后出问题才去这里看。

 

4、总结

今天这个场景很简单,文章开头那个连接里的案例要复杂一点(windows上能够,linux不行)。你们也能够看下。

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

若是同一个类加载器下出现了两个全路径相同的类,天然就冲突了。

相关文章
相关标签/搜索