【问题标题】:Is there a way to force waiting for the end of a java process to end in Scala or Spark?有没有办法强制等待 Java 进程结束以在 Scala 或 Spark 中结束?
【发布时间】:2019-05-13 08:15:59
【问题描述】:

在一个通过 Spark 部署的 Scala 应用程序中,我有一个代码行,它调用一个通过 JNI 执行本机 C++ 代码的 Java 函数。此调用需要时间,如果它不是唯一的同类调用,则会出现资源使用冲突,并带有 *** stack smashing detected ***: <unknown> terminated

这是电话,它的范围:

[spark RDD].mapPartitionsWithIndex(f = (index: Int, it: Iterator[Row]) => {
  val sourceData: String = it.mkString()

  val result: List[List[String]] = new WrapperClass(sourceData, [misc parameters).getResult

  [wrinting result to a file]
}).take(1)

我的WrapperClass.getResult,很简单,长这样:

[java call related variables initialization]

UnitexJni.execUnitexTool("UnitexTool {InstallLingResourcePackage -p " + appliedPkg + " -x " + resDir + "} " + "{" + runScriptCmd + "} " + "{InstallLingResourcePackage -p " + appliedPkg + " -x " + resDir + " --uninstall}")

[retrieving, formatting and returning result]

UnitexJni.execUnitexTool() 是 java 调用。

所以我想知道是否有办法强制等到这个过程结束,然后再使用 Scala、Java 或 Spark 功能调用它。

【问题讨论】:

  • 请在您的问题中添加代码 sn-p,显示您如何使用 JNI 运行此脚本命令。
  • 我第一次没有包含它,因为调用JNI的行非常具体,所以我将它放在这里:UnitexJni.execUnitexTool("UnitexTool {InstallLingResourcePackage -p " + appliedPkg + " -x " + resDir + "} " + "{" + runScriptCmd + "} " + "{InstallLingResourcePackage -p " + appliedPkg + " -x " + resDir + " --uninstall}") RunScript 命令也是要发送到的特定字符串JNI。虽然,据我测试,这个调用做了它应该做的。导致任务冲突的是 Spark Ordonancement。
  • 假设您从 Scala 运行一个 shell 脚本,那么您需要强制 Scala 在此脚本完成之前不要执行任何其他操作以避免冲突。对吗?
  • @MoustafaMahmoud 正确。
  • @OlivierGRACIANNE 请在下面查看我的答案

标签: java scala apache-spark


【解决方案1】:

您可以使用sys.process._ 您将通过脚本路径将shell 脚本传递给下面的处理函数。此外,您需要处理 shell 脚本以获得返回码。例如,If 0 success else failed。请注意行尾的!。您还可以查看更多详细信息以从 tutorial 运行快速命令行

import scala.sys.process.Process
val externalShellScript = Process("sh", Seq(scriptPath)).!    
  if (externalShellScript != 0) {
    throw new Exception(
      "Error in executing external shell script from " + scriptPath)
  }

除非此过程完成,否则 Spark 作业将不会继续。下面是简单的 shell 脚本和输出。

touch test.txt
echo "any massage"

控制台中的输出将是

any massage

【讨论】:

  • 如果我要使用 shell 脚本,那将是完美的答案。但实际上,它是通过 JNI 调用执行本机 C++ 代码的 java 函数。所以我的问题宁愿是我可以分叉一个java进程并积极等待它的返回码。不过感谢您的提示。 '将对我正在做的另一件事有用。
  • 我无法理解您的实际问题,您需要从 Scala 运行 Java 代码并等待它完成吗?
  • 这正是我需要做的。
  • 但在 Scala 中,您可以从库或依赖项中导入和调用 Java 函数。我认为您的问题与依赖关系有关。
  • 我知道这一点。我实际上正在毫无问题地导入依赖项。关键是我不确定 Scala/Spark 如何处理在 java 调用下进行的本机 C++ 长进程。所以我想通过托管代码直接控制它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-12-03
  • 2022-10-04
  • 2015-10-25
  • 2021-11-03
  • 2019-05-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多