如何使用 Spark 和 whisklabs/docker-it-scala 解决 SBT 依赖问题
How to solve SBT Dependency Problem with Spark and whisklabs/docker-it-scala
我已经编写了一个 spark 结构化流应用程序(我正在使用 Scala
和 sbt
),现在我必须创建一个集成测试。不幸的是,我 运行 遇到了一个我无法解决的依赖问题。我正在将 scala 与 sbt 一起使用。
我的依赖如下所示
val xxxxxxx = "xx.xxxx" %% "xxxx-xxxxxxx" %"x.x.x" % "test,it" embeddedExclusions
val sparkCore = "org.apache.spark" %% "spark-core" % "2.4.0" % "provided"
val sparkStreaming = "org.apache.spark" %% "spark-streaming" % "2.4.0" % "provided"
val sparkSql = "org.apache.spark" %% "spark-sql" % "2.4.0" % "provided"
val sparkDse = "com.datastax.dse" % "dse-spark-dependencies" % "6.7.2" % "provided" datastaxDseExclusions
val sparkKafka = "org.apache.spark" %% "spark-sql-kafka-0-10" % "2.4.0" % "provided" sparkExclusions
// val jacksonDatabind = "com.fasterxml.jackson.core" % "jackson-databind" % "2.9.6"
这个xxxxxxx
依赖来自公司的一个依赖,用于集成测试(提供cassandra docker-container等)。这个依赖里面有如下依赖:
val dockerTestkit = "com.whisk" %% "docker-testkit-scalatest" % "0.9.8"
val dockerTestkitImpl = "com.whisk" %% "docker-testkit-impl-spotify" % "0.9.8"
val dockerTestkitConfig = "com.whisk" %% "docker-testkit-config" % "0.9.8"
我遇到的问题是 org.apache.spark
和 com.whisk
中的 com.fasterxml.jackson
依赖项
org.apache.spark
使用 com.fasterxml.jackson
版本 2.6.7
com.whisk
使用 com.fasterxml.jackson
版本 2.9.5
第一种方法:
我从 org.apache.spark
中排除了 com.fasterxml.jackson
依赖项,然后我得到:
[info] ...
[info] Cause: com.fasterxml.jackson.databind.JsonMappingException: Incompatible Jackson version: 2.9.5
[info] at com.fasterxml.jackson.module.scala.JacksonModule$class.setupModule(JacksonModule.scala:64)
[info] at com.fasterxml.jackson.module.scala.DefaultScalaModule.setupModule(DefaultScalaModule.scala:19)
[info] at com.fasterxml.jackson.databind.ObjectMapper.registerModule(ObjectMapper.java:751)
[info] at org.apache.spark.rdd.RDDOperationScope$.<init>(RDDOperationScope.scala:82)
[info] at org.apache.spark.rdd.RDDOperationScope$.<clinit>(RDDOperationScope.scala)
[info] at org.apache.spark.sql.execution.SparkPlan.executeQuery(SparkPlan.scala:152)
[info] at org.apache.spark.sql.execution.SparkPlan.execute(SparkPlan.scala:127)
[info] at org.apache.spark.sql.execution.QueryExecution.toRdd$lzycompute(QueryExecution.scala:80)
[info] at org.apache.spark.sql.execution.QueryExecution.toRdd(QueryExecution.scala:80)
[info] at org.apache.spark.sql.cassandra.CassandraSourceRelation.insert(CassandraSourceRelation.scala:131)
[info] ...
第二种方法:
我从 xxxxxxx
中排除 com.fasterxml.jackson
,然后我得到:
[error] Caused by: java.lang.ClassNotFoundException: com.fasterxml.jackson.databind.deser.std.ReferenceTypeDeserializer
[error] at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
[error] at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
[error] at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
[error] at java.lang.ClassLoader.defineClass1(Native Method)
[error] at java.lang.ClassLoader.defineClass(ClassLoader.java:763)
[error] at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
[error] at java.net.URLClassLoader.defineClass(URLClassLoader.java:467)
[error] at java.net.URLClassLoader.access0(URLClassLoader.java:73)
[error] at java.net.URLClassLoader.run(URLClassLoader.java:368)
[error] at java.net.URLClassLoader.run(URLClassLoader.java:362)
[error] at java.security.AccessController.doPrivileged(Native Method)
[error] at java.net.URLClassLoader.findClass(URLClassLoader.java:361)
[error] at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
[error] at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
[error] at com.fasterxml.jackson.datatype.guava.GuavaModule.setupModule(GuavaModule.java:55)
[error] at com.fasterxml.jackson.databind.ObjectMapper.registerModule(ObjectMapper.java:718)
[error] at com.spotify.docker.client.ObjectMapperProvider.<clinit>(ObjectMapperProvider.java:74)
[error] at com.spotify.docker.client.DockerConfigReader.<clinit>(DockerConfigReader.java:58)
[error] at com.spotify.docker.client.auth.ConfigFileRegistryAuthSupplier.<init>(ConfigFileRegistryAuthSupplier.java:47)
[error] at com.spotify.docker.client.DefaultDockerClient$Builder.build(DefaultDockerClient.java:3141)
我假设 com.fasterxml.jackson
的旧版本没有这个 class。
问题
- 有谁知道我该如何解决这个问题?
- 是否可以导入两个
com.fasterxml.jackson
依赖版本?
我尝试了两种方法
1.方法: Shading xxxxxxx
项目中的依赖
我将程序集插件添加到 plugin.sbt
addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.14.7")
并在 build.sbt
中添加了一些着色规则。我正在为 xxxxxxx
项目
创建一个 fat-jar
assemblyShadeRules in assembly := Seq(
ShadeRule
.rename("com.fasterxml.jackson.**" -> "embedded.com.fasterxml.jackson.@1")
.inAll
)
阴影有效。 com.fasterxml.jackson
项目中的所有 com.fasterxml.jackson
依赖项都被重写为 embedded.com.fasterxml.jackson.*
。 (我解压缩 jar 并反编译 类,看看发生了什么)
不幸的是,重写并没有解决root
项目中的问题(而且我不知道为什么)。所以我尝试了:
2.Approach 在 commonSettings
中使用 dependencyOverrides
我在 root
项目中添加了以下依赖项:
val jacksonCore = "com.fasterxml.jackson.core" % "jackson-core" % "2.9.6"
val jacksonDatabind = "com.fasterxml.jackson.core" % "jackson-databind" % "2.9.6"
val jacksonModule = "com.fasterxml.jackson.module" %% "jackson-module-scala" % "2.9.6"
我没有从
中排除com.fasterxml.jackson
依赖
- Apache Spark,也不
- 来自
xxxxxxx
我在常用设置中添加了以下设置:
lazy val commonSettings = Seq(
scalaVersion := library.version.scala,
...
dependencyOverrides ++= Seq(
library.jacksonDatabind,
library.jacksonCore,
library.jacksonModule
),
...
)
成功了,异常消失了。不幸的是,我无法解释为什么这会起作用(以及如何起作用)以及为什么阴影不起作用。 :(
我已经编写了一个 spark 结构化流应用程序(我正在使用 Scala
和 sbt
),现在我必须创建一个集成测试。不幸的是,我 运行 遇到了一个我无法解决的依赖问题。我正在将 scala 与 sbt 一起使用。
我的依赖如下所示
val xxxxxxx = "xx.xxxx" %% "xxxx-xxxxxxx" %"x.x.x" % "test,it" embeddedExclusions
val sparkCore = "org.apache.spark" %% "spark-core" % "2.4.0" % "provided"
val sparkStreaming = "org.apache.spark" %% "spark-streaming" % "2.4.0" % "provided"
val sparkSql = "org.apache.spark" %% "spark-sql" % "2.4.0" % "provided"
val sparkDse = "com.datastax.dse" % "dse-spark-dependencies" % "6.7.2" % "provided" datastaxDseExclusions
val sparkKafka = "org.apache.spark" %% "spark-sql-kafka-0-10" % "2.4.0" % "provided" sparkExclusions
// val jacksonDatabind = "com.fasterxml.jackson.core" % "jackson-databind" % "2.9.6"
这个xxxxxxx
依赖来自公司的一个依赖,用于集成测试(提供cassandra docker-container等)。这个依赖里面有如下依赖:
val dockerTestkit = "com.whisk" %% "docker-testkit-scalatest" % "0.9.8"
val dockerTestkitImpl = "com.whisk" %% "docker-testkit-impl-spotify" % "0.9.8"
val dockerTestkitConfig = "com.whisk" %% "docker-testkit-config" % "0.9.8"
我遇到的问题是 org.apache.spark
和 com.whisk
com.fasterxml.jackson
依赖项
org.apache.spark
使用com.fasterxml.jackson
版本2.6.7
com.whisk
使用com.fasterxml.jackson
版本2.9.5
第一种方法:
我从 org.apache.spark
中排除了 com.fasterxml.jackson
依赖项,然后我得到:
[info] ...
[info] Cause: com.fasterxml.jackson.databind.JsonMappingException: Incompatible Jackson version: 2.9.5
[info] at com.fasterxml.jackson.module.scala.JacksonModule$class.setupModule(JacksonModule.scala:64)
[info] at com.fasterxml.jackson.module.scala.DefaultScalaModule.setupModule(DefaultScalaModule.scala:19)
[info] at com.fasterxml.jackson.databind.ObjectMapper.registerModule(ObjectMapper.java:751)
[info] at org.apache.spark.rdd.RDDOperationScope$.<init>(RDDOperationScope.scala:82)
[info] at org.apache.spark.rdd.RDDOperationScope$.<clinit>(RDDOperationScope.scala)
[info] at org.apache.spark.sql.execution.SparkPlan.executeQuery(SparkPlan.scala:152)
[info] at org.apache.spark.sql.execution.SparkPlan.execute(SparkPlan.scala:127)
[info] at org.apache.spark.sql.execution.QueryExecution.toRdd$lzycompute(QueryExecution.scala:80)
[info] at org.apache.spark.sql.execution.QueryExecution.toRdd(QueryExecution.scala:80)
[info] at org.apache.spark.sql.cassandra.CassandraSourceRelation.insert(CassandraSourceRelation.scala:131)
[info] ...
第二种方法:
我从 xxxxxxx
中排除 com.fasterxml.jackson
,然后我得到:
[error] Caused by: java.lang.ClassNotFoundException: com.fasterxml.jackson.databind.deser.std.ReferenceTypeDeserializer
[error] at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
[error] at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
[error] at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
[error] at java.lang.ClassLoader.defineClass1(Native Method)
[error] at java.lang.ClassLoader.defineClass(ClassLoader.java:763)
[error] at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
[error] at java.net.URLClassLoader.defineClass(URLClassLoader.java:467)
[error] at java.net.URLClassLoader.access0(URLClassLoader.java:73)
[error] at java.net.URLClassLoader.run(URLClassLoader.java:368)
[error] at java.net.URLClassLoader.run(URLClassLoader.java:362)
[error] at java.security.AccessController.doPrivileged(Native Method)
[error] at java.net.URLClassLoader.findClass(URLClassLoader.java:361)
[error] at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
[error] at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
[error] at com.fasterxml.jackson.datatype.guava.GuavaModule.setupModule(GuavaModule.java:55)
[error] at com.fasterxml.jackson.databind.ObjectMapper.registerModule(ObjectMapper.java:718)
[error] at com.spotify.docker.client.ObjectMapperProvider.<clinit>(ObjectMapperProvider.java:74)
[error] at com.spotify.docker.client.DockerConfigReader.<clinit>(DockerConfigReader.java:58)
[error] at com.spotify.docker.client.auth.ConfigFileRegistryAuthSupplier.<init>(ConfigFileRegistryAuthSupplier.java:47)
[error] at com.spotify.docker.client.DefaultDockerClient$Builder.build(DefaultDockerClient.java:3141)
我假设 com.fasterxml.jackson
的旧版本没有这个 class。
问题
- 有谁知道我该如何解决这个问题?
- 是否可以导入两个
com.fasterxml.jackson
依赖版本?
我尝试了两种方法
1.方法: Shading xxxxxxx
项目中的依赖
我将程序集插件添加到 plugin.sbt
addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.14.7")
并在 build.sbt
中添加了一些着色规则。我正在为 xxxxxxx
项目
assemblyShadeRules in assembly := Seq(
ShadeRule
.rename("com.fasterxml.jackson.**" -> "embedded.com.fasterxml.jackson.@1")
.inAll
)
阴影有效。 com.fasterxml.jackson
项目中的所有 com.fasterxml.jackson
依赖项都被重写为 embedded.com.fasterxml.jackson.*
。 (我解压缩 jar 并反编译 类,看看发生了什么)
不幸的是,重写并没有解决root
项目中的问题(而且我不知道为什么)。所以我尝试了:
2.Approach 在 commonSettings
dependencyOverrides
我在 root
项目中添加了以下依赖项:
val jacksonCore = "com.fasterxml.jackson.core" % "jackson-core" % "2.9.6"
val jacksonDatabind = "com.fasterxml.jackson.core" % "jackson-databind" % "2.9.6"
val jacksonModule = "com.fasterxml.jackson.module" %% "jackson-module-scala" % "2.9.6"
我没有从
中排除com.fasterxml.jackson
依赖
- Apache Spark,也不
- 来自
xxxxxxx
我在常用设置中添加了以下设置:
lazy val commonSettings = Seq(
scalaVersion := library.version.scala,
...
dependencyOverrides ++= Seq(
library.jacksonDatabind,
library.jacksonCore,
library.jacksonModule
),
...
)
成功了,异常消失了。不幸的是,我无法解释为什么这会起作用(以及如何起作用)以及为什么阴影不起作用。 :(