4

我与传递依赖有冲突。覆盖、排除或强制没有帮助。我还能做些什么来将正确版本的库放入 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)

这与配置库的过时版本有关,如何解决类型安全配置上的 NoSuchMethodError?. 也通过以下方式确认:

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'
    }
}

没有给出正确的版本。

结果

所有变体都失败并出现相同的错误

怎么了?必须有一种方法可以强制使用所需的版本。

4

1 回答 1

2

您遇到的问题与您所描述的完全相反。

您在项目中尝试的不同方法都确保版本com.typesafe:config1.3.x.

但是,在添加时,org.locationtech.geomesa:geomesa-hbase-spark-runtime_2.11:2.0.1您会引入一些已经具有来自com.typesafe:config但来自1.2行的类的依赖项。当您创建胖 jar 时,该版本会覆盖该1.3行中的类。

这可以通过解压你的 fat jar 并运行来看到:

$ 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

另一种解决方案是准确找出包含这些的胖罐,看看是否可以将其从自己的胖罐中排除。

于 2018-05-30T16:57:41.750 回答