代码之家  ›  专栏  ›  技术社区  ›  Georg Heiler

传递依赖关系的渐变强制版本不起作用。似乎没有排除、覆盖或强制应用

  •  1
  • Georg Heiler  · 技术社区  · 7 年前

    我和传递依赖关系有冲突。重写、排除或强制不起作用。我还能做些什么把正确版本的库放入jar中呢? 完整的代码应该是。建立 https://github.com/geoHeil/gradle-dependency-resolution 但其主要部分如下所述。

    问题描述

    正在执行

    ./gradlew shadowJar
    

    禁用geomesa依赖项(它会拉入过时版本的typesafe/lightbend配置库):

    dependencies {
    
        compile "com.github.kxbmap:configs_2.11:0.4.4"
        //compile "org.locationtech.geomesa:geomesa-hbase-spark-runtime_2.11:2.0.1"
    }
    

    执行jar

    java -jar build/libs/gradleThing-all.jar                         
    

    hello
    my config is: Success(Job1Configuration(frequencyCounting))
    

    启用依赖项时:

    ./gradlew shadowJar
    java -jar build/libs/gradleThing-all.jar                         
    

    它失败了

    hello
    Exception in thread "main" java.lang.Exception: Failed to start. There is a problem with the configuration: Vector([extract] com.typesafe.config.Config.hasPathOrNull(Ljava/lang/String;)Z)
    

    与配置库的过时版本相关, how to resolve NoSuchMethodError on typesafe config? . 也可通过以下方式确认:

    gradle dependencyInsight --dependency om.typesafe:config
    
    > Task :dependencyInsight
    com.typesafe:config:1.3.1 (conflict resolution)
       variant "runtime" [
          Requested attributes not found in the selected variant:
             org.gradle.usage = java-api
       ]
    \--- com.github.kxbmap:configs_2.11:0.4.4
         \--- compileClasspath
    
    com.typesafe:config:1.2.1 -> 1.3.1
       variant "runtime" [
          Requested attributes not found in the selected variant:
             org.gradle.usage = java-api
       ]
    +--- org.locationtech.geomesa:geomesa-convert-avro_2.11:2.0.1
    |    \--- org.locationtech.geomesa:geomesa-convert-all_2.11:2.0.1
    |         +--- org.locationtech.geomesa:geomesa-tools_2.11:2.0.1
    |         |    \--- org.locationtech.geomesa:geomesa-hbase-spark-runtime_2.11:2.0.1
    |         |         \--- compileClasspath
    ...
    

    如何将可传递依赖项修复为所需的1.3.3版本?

    我的解决方案

    正在尝试设置:

    compile("org.locationtech.geomesa:geomesa-hbase-spark-runtime_2.11:2.0.1") {
                    exclude group: 'com.typesafe', module: 'config'
                }
    

    再次运行jar也会因同样的问题而失败。

    也是一个约束 https://docs.gradle.org/current/userguide/managing_transitive_dependencies.html#sec:dependency_constraints 像:

    implementation("com.typesafe:config")
        constraints {
            implementation("com.typesafe:config:1.3.3") {
                because 'previous versions miss a method https://stackoverflow.com/questions/40610816/how-to-resolve-nosuchmethoderror-on-typesafe-config'
            }
        }
    

    或使用武力 https://docs.gradle.org/current/userguide/managing_transitive_dependencies.html#sec:enforcing_dependency_version 像:

    implementation('com.typesafe:config:1.3.3') {
            force = true
        }
    

    或类似:

    configurations.all {
        resolutionStrategy {
            force 'com.typesafe:config:1.3.3'
        }
    }
    

    没有给出正确的版本。

    结果

    所有变量都失败,错误相同

    怎么了?必须有一种方法来强制实现所需的版本。

    1 回复  |  直到 7 年前
        1
  •  2
  •   Louis Jacomet    7 年前

    你的问题与你所描述的完全相反。

    您在项目中尝试的不同操作都会确保 com.typesafe:config 是一个 1.3.x .

    但是,添加时 org.locationtech.geomesa:geomesa-hbase-spark-runtime_2.11:2.0.1 您引入了一些依赖项,这些依赖项已经具有 com.typesafe:配置 但是从 1.2 线。当您创建胖jar时,该版本会覆盖 1.3 线。

    这可以通过减压和跑步来看到:

    $ javap com/typesafe/config/Config.class | grep hasPath
      public abstract boolean hasPath(java.lang.String);
    

    显示出 hasPathOrNull 缺少方法。

    这个阴影问题在 https://issues.apache.org/jira/browse/SPARK-9441

    鉴于此,如果可能的话,最简单的方法就是降级 "com.github.kxbmap:configs_2.11 到依赖的版本 com.typesafe:config:1.2.x

    另一个解决方案是找出包含这些的确切的胖罐,并看看是否可以从自己的胖罐中排除它。

    推荐文章