替换默认导入的库 Spark 的类路径

Posted

技术标签:

【中文标题】替换默认导入的库 Spark 的类路径【英文标题】:Replace library imported by default Spark's classpath 【发布时间】:2019-04-05 13:20:04 【问题描述】:

我目前正在处理 Spark 2.1.0 中的一个项目,我需要导入一个 Spark 本身已经依赖的库。特别是,我希望 org.roaringbitmap:RoaringBitmap:0.7.42 替换 org.roaringbitmap:RoaringBitmap:0.5.11org.apache.spark:spark-core_2.11:2.1.0.cloudera1org.apache.spark:spark-sql_2.11:2.1.0.cloudera1 都依赖的库)。

我在build.gradle 中的依赖项如下

dependencies 
    compile 'org.apache.spark:spark-core_2.11:2.1.0.cloudera1'
    runtime ('org.apache.spark:spark-core_2.11:2.1.0.cloudera1') 
        exclude group: 'org.roaringbitmap'
    
    compile 'org.apache.spark:spark-sql_2.11:2.1.0.cloudera1'
    runtime ('org.apache.spark:spark-sql_2.11:2.1.0.cloudera1') 
        exclude group: 'org.roaringbitmap'
    
    compile 'org.roaringbitmap:RoaringBitmap:0.7.42'
    implementation 'org.roaringbitmap:RoaringBitmap'
    constraints 
        implementation('org.roaringbitmap:RoaringBitmap:0.7.42') 
            because 'because of transitive dependency'
        
    

gradle -q dependencyInsight --dependency org.roaringbitmap 的输出显示依赖已更新

org.roaringbitmap:RoaringBitmap -> 0.7.42
   variant "default+runtime" [
      org.gradle.status = release (not requested)
      Requested attributes not found in the selected variant:
         org.gradle.usage  = java-api
   ]
\--- compileClasspath

org.roaringbitmap:RoaringBitmap:0.5.11 -> 0.7.42
   variant "default+runtime" [
      org.gradle.status = release (not requested)
      Requested attributes not found in the selected variant:
         org.gradle.usage  = java-api
   ]
\--- org.apache.spark:spark-core_2.11:2.1.0.cloudera1
     +--- compileClasspath
     +--- org.apache.spark:spark-sql_2.11:2.1.0.cloudera1
     |    \--- compileClasspath
     \--- org.apache.spark:spark-catalyst_2.11:2.1.0.cloudera1
          \--- org.apache.spark:spark-sql_2.11:2.1.0.cloudera1 (*)

不幸的是,当我使用spark2-submit 运行我的应用程序时,运行时依赖项的实际版本是org.roaringbitmap:RoaringBitmap:0.5.11

如何强制我的应用程序使用所需版本的 RoaringBitmap?

【问题讨论】:

我无法回答具体问题,但您确定“强制”版本是要走的路吗?它只有在 5.11 和 7.42 是二进制兼容的情况下才有效,也就是说,每个可访问代码的类和方法名称、参数和声明的异常都严格相同。如果 Spark 在 5.11 中调用 RoaringBitmap 的 A#whatever() 并且此方法在 7.42 中已更改(或被删除),它崩溃。您最好的选择是使用 Spark 的版本重新设计您的应用程序,或者使用shading。 【参考方案1】:

无论如何,我相信 CDH 提供的库优先于您的库。

您可以使用 spark2-shell 中的下一段代码检查这一点:

import java.lang.ClassLoader
val cl = ClassLoader.getSystemClassLoader
cl.asInstanceOf[java.net.URLClassLoader].getURLs.foreach(println)

一般我使用shade插件来克服它。

【讨论】:

【参考方案2】:

Spark 可以选择将用户类路径优先于自己的路径。 Classpath resolution between spark uber jar and spark-submit --jars when similar classes exist in both

您很可能还应该研究阴影。

【讨论】:

以上是关于替换默认导入的库 Spark 的类路径的主要内容,如果未能解决你的问题,请参考以下文章

Android编译时动态替换Jar包中的类

指定java代理的类路径

在 Spark 客户端模式下为执行程序添加额外的类路径

新/删除不匹配

从 Spark 替换 hive 分区

是否有用 html 代码替换字符的库函数? [蟒蛇] [重复]