apache-spark - spark 提交应用程序中的 Scala ScriptEngine 问题

标签 apache-spark classloader spark-submit scriptengine scala-script

我正在开发一个让用户编写 DSLS 的系统,并在运行时将其作为我的类型的实例加载,这些可以应用于 RDD 之上。整个应用程序作为一个 spark-submit 应用程序运行,我使用 ScriptEngine 引擎编译用 Scala 本身编写的 DSL。每个测试在 SBT 和 IntelliJ 中都运行良好。但是在执行 spark-submit 时,我的 fat-jar 中可用的我自己的类型无法在脚本中导入。我按如下方式初始化脚本引擎。

val engine: ScriptEngine = new ScriptEngineManager().getEngineByName("scala")
private val settings: Settings = engine.asInstanceOf[scala.tools.nsc.interpreter.IMain].settings
settings.usejavacp.value = true

settings.embeddedDefaults[DummyClass]
private val loader: ClassLoader = Thread.currentThread().getContextClassLoader
settings.embeddedDefaults(loader)

这似乎是 spark-submit 期间类加载器的问题。但是我无法弄清楚为什么在我的 jar 中我自己的类型也有 spark-submit 的主程序在我的脚本中不可用的原因,我的脚本是在同一个 JVM 中创建的。 scala scala-compiler、scala-reflect 和 scala-library 版本是 2.11.8。一些帮助将不胜感激。

最佳答案

我找到了可行的解决方案。通过查看代码和大量调试,我终于发现 ScriptEngine 通过使用用于创建它的 Classloader 的 Classpath 字符串为自己创建了一个 Classloader。在 spark-submit 的情况下,spark 创建一个特殊的类加载器,它可以从本地和 hdfs 文件中读取。但是从这个类加载器获得的类路径字符串不会有我们在 HDFS 中存在的应用程序 jar。

通过在初始化之前手动将我的应用程序 jar 附加到 ScriptEngine 类路径,它解决了我的问题。为此,我必须在附加之前将 HDFS 中的应用程序 jar 本地下载到本地。

关于apache-spark - spark 提交应用程序中的 Scala ScriptEngine 问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51723400/

相关文章:

Spark中Mysql数据处理

apache-spark - 如何使用 usingColumns 连接 spark 中的嵌套列

java - A类不等于A类

java - 如何使用maven制作可执行jar?

hadoop - Spark程序在群集上运行非常慢

apache-spark - Spark java.lang.OutOfMemoryError : Java Heap space

apache-spark - 如何在spark-submit命令中引用.so文件

scala - 在 Spark 集群中运行用 Scala 编写的 Spark 代码

apache-spark - 如何将流式数据集写入 Hive?

jar - 通过 sbt 打包的 one-jar 内的类路径资源