本文从实际工作中的一个bug出发,讲解了业务的背景、分析了问题产生的原因、介绍了解决问题的思路,同时介绍了Maven的依赖机制。业务场景
最近在工作中,使用Dubbo调用远程服务,需要依赖被调用方(dubbo service provider)提供的一些jar包。
下面是maven和dubbo的相关配置。
pom.xml
com.dubbo.service.providerfoo-api1.0
dubbo-serivce-provider.xml
发现问题
项目启动后,出现如下异常
java.lang.NoSuchMethodError: com.google.common.base.Platform.systemNanoTime()
问题原因
通过Eclipse查看依赖树发现,foo-api所依赖的jar与项目中的jar发生了冲突。
可以将如上场景抽象为下面的逻辑:
```
A依赖
-> B
D依赖
-> A
-> B
```
因为Maven拥有传递依赖的特性,因此真实的依赖树是:
```
A依赖
-> B
D依赖
-> A
-> B
-> B
```
因此D项目发生了依赖冲突。
相关知识:依赖传递(Transitive Dependencies)
依赖传递(Transitive Dependencies)是Maven 2.0开始的提供的特性,依赖传递的好处是不言而喻的,可以让我们不需要去寻找和发现所必须依赖的库,而是将会自动将需要依赖的库帮我们加进来。
例如A依赖了B,B依赖了C和D,那么你就可以在A中,像主动依赖了C和D一样使用它们。并且传递的依赖是没有数量和层级的限制的,非常方便。
但依赖传递也不可避免的会带来一些问题,例如:
- 当依赖层级很深的时候,可能造成循环依赖(cyclic dependency)
- 当依赖的数量很多的时候,依赖树会非常大
针对这些问题,Maven提供了很多管理依赖的特性:
依赖调节(Dependency mediation)
依赖调节是为了解决版本不一致的问题(multiple versions),并采取就近原