您当前的位置: 首页 >  ar

Bulut0907

暂无认证

  • 0浏览

    0关注

    346博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

Apache Maven依赖的传递性、依赖的排除、版本仲裁、jar包冲突解决

Bulut0907 发布时间:2022-07-07 09:17:04 ,浏览量:0

目录
  • 1. 依赖的传递性
    • 1.1 概念
    • 1.2 传递的原则
  • 2. 依赖的排除
    • 2.1 概念
    • 2.2 配置方式
  • 3. 版本仲裁
  • 4. jar包冲突
    • 4.1 jar包冲突原因
    • 4.2 解决办法
      • 4.2.1 IDEA的Maven Helper插件的使用
      • 4.2.2 Maven的enforcer插件使用
    • 4.3 用父工程做dependencyManagement统一管理依赖

1. 依赖的传递性 1.1 概念

A依赖B,B依赖C,那么A能不能直接使用C

1.2 传递的原则

A依赖B,B依赖C,A能不能直接使用C,取决于B依赖C时使用的依赖范围scope

  • B依赖C时使用compile:A能直接使用C
  • B依赖C时使用test或provided范围,A不能直接使用C
2. 依赖的排除 2.1 概念

当A依赖B,A又依赖C,但B和C依赖一个包的两个不同版本,这就可能发生版本冲突,需要使用依赖排序将其中一个排除掉

版本冲突

2.2 配置方式

下面例子是iceberg-flink不引入slf4j-api的依赖传递

    
      org.apache.iceberg
      iceberg-flink
      0.13.2
      
        
          org.slf4j
          slf4j-api
        
      
    
3. 版本仲裁

遵循以下原则: 1. 最短路径优先

在下面的例子中,对模块pro25-module-a来说,Maven会采用1.2.12版本

最短路径优先 2. 路径相同时先声明者优先

在下面的例子中,在pro29-module-x中,先对pro30-module-y进行依赖声明,再对pro31-module-z进行依赖声明。所以Maven会采用1.2.17版本

先声明者优先

4. jar包冲突 4.1 jar包冲突原因

主要体现为找不到类或找不到方法

  • 抛异常:找不到类

此时抛出的常见的异常类型:

java.lang.ClassNotFoundException:编译过程中找不到类
java.lang.NoClassDefFoundError:运行过程中找不到类
java.lang.LinkageError:不同类加载器分别加载的多个类有相同的全限定名

原因:假如我们需要类A,在B-1.1.jar包中。但通过版本仲裁,采用了B-1.0.jar。而B-1.0.jar没有类A,就会抛找不到类A的异常

  • 抛异常:找不到方法

程序找不到符合预期的方法。这种情况多见于通过反射调用方法,所以经常会导致:java.lang.NoSuchMethodError

  • 没报错但结果不对

发生这种情况比较典型的原因是:两个jar包中的类分别实现了同一个接口,而这两个实现类恰巧是同一个名字。本来想使用第一个,确使用了第二个,虽然没报错,但由于实现细节不一样,导致结果不对

4.2 解决办法

基本思路主要有两步:

  1. 把彼此冲突的jar包找到
  2. 在冲突的jar包中选定一个。具体可以通过exclusions排除依赖,或明确声明依赖
4.2.1 IDEA的Maven Helper插件的使用

能够给我们罗列出来同一个jar包的不同版本,以及它们的来源。但是对不同jar包中同名的类没有办法

先安装Maven Helper插件 Maven Helper完整的pom.xml内容如下:


  4.0.0

  com.hh
  maven-learn
  0.1

  
    
      org.apache.flink
      flink-core
      1.15.0
    

    
      com.ververica
      flink-connector-mysql-cdc
      2.2.0
    

  


查看冲突的依赖如下 查看冲突的依赖

4.2.2 Maven的enforcer插件使用

既可以检测同一个jar包的不同版本,又可以检测不同jar包中同名的类

添加maven-enforcer-plugin插件到pom.xml,并添加extra-enforcer-rules插件依赖,然后开启重复的类检测功能

完整的pom.xml内容如下:


  4.0.0

  com.hh
  maven-learn
  0.1

  
    
      org.apache.flink
      flink-core
      1.15.0
    

    
      com.ververica
      flink-connector-mysql-cdc
      2.2.0
    

  

  
    
      
        
          org.apache.maven.plugins
          maven-enforcer-plugin
          3.0.0-M3
          
            
              enforce-dependencies
              validate
              
                display-info
                enforce
              
            
          
          
            
            
            
              org.codehaus.mojo
              extra-enforcer-rules
              1.3
            
          
          
            
              
              
                true
              
            
          

        
      
    
  



执行如下命令进行重复类检测

C:\Users\dell\Desktop\maven-learn>mvn clean enforcer:enforce
[INFO] Scanning for projects...
[INFO] 
[INFO] -------------------------< com.hh:maven-learn >-------------------------
[INFO] Building maven-learn 0.1
[INFO] --------------------------------[ jar ]---------------------------------
[INFO] 
[INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ maven-learn ---
[INFO] 
[INFO] --- maven-enforcer-plugin:3.0.0-M3:enforce (default-cli) @ maven-learn ---
[INFO] Adding ignore: module-info
[INFO] Adding ignore: META-INF/versions/*/module-info
[WARNING] Could not find com.ververica:flink-connector-mysql-cdc:jar:2.2.0:compile at null
[WARNING] Could not find org.apache.flink:flink-core:jar:1.15.0:compile at null
[WARNING] Rule 0: org.apache.maven.plugins.enforcer.BanDuplicateClasses failed with message:
Duplicate classes found:

  Found in:
    javax.xml.bind:jaxb-api:jar:2.3.0:compile
    jakarta.xml.bind:jakarta.xml.bind-api:jar:2.3.2:compile
  Duplicate classes:
    javax/xml/bind/annotation/XmlValue.class
    javax/xml/bind/ContextFinder.class
......省略部分......
    javax/xml/bind/helpers/AbstractMarshallerImpl.class

  Found in:
    com.ververica:flink-connector-debezium:jar:2.2.0:compile
    io.debezium:debezium-embedded:jar:1.5.4.Final:compile
  Duplicate classes:
    io/debezium/embedded/EmbeddedEngineChangeEvent.class

  Found in:
    javax.ws.rs:javax.ws.rs-api:jar:2.1.1:compile
    jakarta.ws.rs:jakarta.ws.rs-api:jar:2.1.6:compile
  Duplicate classes:
    javax/ws/rs/ext/RuntimeDelegate$HeaderDelegate.class
    javax/ws/rs/HEAD.class
......省略部分......
    javax/ws/rs/client/CompletionStageRxInvoker.class

  Found in:
    jakarta.activation:jakarta.activation-api:jar:1.2.1:compile
    javax.activation:activation:jar:1.1.1:compile
  Duplicate classes:
    javax/activation/DataContentHandlerFactory.class
    javax/activation/SecuritySupport$2.class
......省略部分......
    javax/activation/URLDataSource.class

[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  2.215 s
[INFO] Finished at: 2022-07-01T16:06:35+08:00
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-enforcer-plugin:3.0.0-M3:enforce (default-cli) on project maven-learn: Some Enforcer rules
 have failed. Look above for specific messages explaining why the rule failed. -> [Help 1]
[ERROR]
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR]
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoExecutionException

C:\Users\dell\Desktop\maven-learn>

这里虽然构建失败,但是不影响我们查看重复的类

4.3 用父工程做dependencyManagement统一管理依赖

推荐一个公司或部门,用一个父工程做dependencyManagement,统一管理依赖关系,其它项目只需引用即可,避免每个人都去解决jar包冲突的问题。如果出现jar包冲突问题,只需修改该父工程的dependencyManagement就可以了

关注
打赏
1664501120
查看更多评论
立即登录/注册

微信扫码登录

0.0375s