美文网首页
maven jar包冲突原理与解决办法

maven jar包冲突原理与解决办法

作者: 赤道的飞雪_f6e1 | 来源:发表于2019-11-24 11:18 被阅读0次

jar 包冲突原因

Caused by:java.lang.NoSuchMethodError
Caused by: java.lang.ClassNotFoundException

大概就是jar包冲突(今天遇到的是第一种)

依赖传递

 A依赖
            -> B
 D依赖
      -> A
      -> B

因为Maven拥有传递依赖的特性,因此真实的依赖树是:

A依赖
      -> B

  D依赖
      -> A
          -> B
      -> B

依赖传递问题:

  • 当依赖层级很深的时候,可能造成循环依赖(cyclic dependency)
  • 当依赖的数量很多的时候,依赖树会非常大

查找依赖冲突

idea插件 dependency analyzer插件,如下图,可以清晰的看到依赖树,进而决定如何解决


image.png

maven提供的解决方法:

依赖调节--就近原则

例如:
A项目通过依赖传递依赖了两个版本的D:
A -> B -> C -> ( D 2.0) , A -> E -> (D 1.0)
那么最终A依赖的D的version将会是1.0,因为1.0对应的层级更少,也就是更近。

依赖管理

Dependency management,可以大大简化子POM的依赖声明。
即父pom.xml声明版本,子pom.xml
不用指定版本号。

  • 依赖范围(Dependency scope)
     <scope>system</scope>

有以下参数

  • compile: 编译依赖范围(默认)
  • test: 测试依赖范围 典型例子是JUnit,它只有在编译测试代码及运行测试的时候才需要
  • provided: 已提供依赖范围
    使用此依赖范围的Maven依赖,对于编译和测试classpath有效,但在运行时无效。
    典型例子是servlet-api,编译和测试项目的时候需要该依赖,但在运行项目的时候,由于容器已经提供,就不需要Maven重复地引入一遍。
  • runtime: 运行时依赖范围。
    使用此依赖范围的Maven依赖,对于测试和运行classpath有效,但在编译主代码时无效。
    典型例子是JDBC驱动实现,项目主代码的编译只需要JDK提供的JDBC接口,只有在执行测试或者运行项目的时候才需要实现上述接口的具体JDBC驱动。

排除依赖(Excluded dependencies)

排除不需要从所依赖的项目中传递过来的依赖 <exclude/>

可选依赖(Optional dependencies)

被依赖的项目主动不把可以传递的依赖传递下去

解决方法

使用Maven提供的Optional和Exclusions来控制依赖的传递
Optional 定义后,该依赖只能在本项目中传递,不会传递到引用该项目的父项目中,父项目需要主动引用该依赖才行。

A
  -> B
D
  -> A
  -> B

A/pom.xml如下:

<dependency>
    <groupId>com.zxa</groupId>
    <artifactId>B</artifactId>
    <version>1.0</version>
    <optional>true</optional>
</dependency>

这种情况下,此项目对B的依赖将不会传递给D
Exclusions 则是主动排除子项目传递过来的依赖。

<dependency>
    <groupId>com.bar</groupId>
    <artifactId>A</artifactId>
    <version>1.0</version>
    <exclusions>
        <exclusion>
            <groupId>com.bar</groupId>
            <artifactId>B</artifactId>
        </exclusion>
    </exclusions>
</dependency>

A

相关文章

网友评论

      本文标题:maven jar包冲突原理与解决办法

      本文链接:https://www.haomeiwen.com/subject/kdclwctx.html