【问题标题】:ProcessBuilder - Start another process / JVM in Scala - HowTo?ProcessBuilder - 在 Scala 中启动另一个进程/JVM - HowTo?
【发布时间】:2010-07-21 12:56:53
【问题描述】:

我已经处理过用 Java 启动另一个 VM。 见ProcessBuilder - Start another process / JVM - HowTo?

出于某种原因,我无法在 Scala 中做同样的事情。 这是我的代码

object NewProcTest {
  def main(args :Array[String]) {
    println("Main")
//    val clazz = classOf[O3]
    val clazz = O4.getClass
    Proc.spawn(clazz, true)
    println("fin")
  }
}

object Proc{
  def spawn(clazz :Class[_],  redirectStream :Boolean)  {
    val separator = System.getProperty("file.separator")
    val classpath = System.getProperty("java.class.path")
    val path = System.getProperty("java.home") + 
      separator + "bin" + separator + "java"
    val processBuilder = 
            new ProcessBuilder(path, "-cp", 
            classpath, 
            clazz.getCanonicalName())
    processBuilder.redirectErrorStream(redirectStream)
    val process = processBuilder.start()
    process.waitFor()
    System.out.println("Fin")
  }
}

我尝试在对象和类中定义 main。两者都在同一个 .scala 文件中或在单独的文件中。

我做错了什么?

【问题讨论】:

  • 您应该提供更多关于您在编写该代码后所做的事情的详细信息:您使用了哪些工具/命令?结果如何?
  • 细节和我的java问题一样。类 O3 { def main(args :Array[String]) { println("O3") } }

标签: scala process jvm fork scala-2.8


【解决方案1】:

问题似乎是对象的类名具有“$”后缀。

如果去掉该后缀,则从 ProcessBuilder 触发的 Java 调用行会起作用。

我在下面破解了一些东西来展示几个测试用例。我还不确定为什么会这样,但至少它提供了一种解决方法。

import java.io.{InputStreamReader, BufferedReader}
import System.{getProperty => Prop}

object O3 {def main(args: Array[String]) {println("hello from O3")}}

package package1 {
  object O4 {def main(args: Array[String]) {println("hello from O4")}}
}

object NewProcTest {
  val className1 = O3.getClass().getCanonicalName().dropRight(1)
  val className2 = package1.O4.getClass().getCanonicalName().dropRight(1)
  val sep        = Prop("file.separator")
  val classpath  = Prop("java.class.path")
  val path       = Prop("java.home")+sep+"bin"+sep+"java"

  println("className1 = " + className1)
  println("className2 = " + className2)

  def spawn(className:      String,
            redirectStream: Boolean) {
    val processBuilder = new ProcessBuilder(path, "-cp", classpath, className)
    val pbcmd          = processBuilder.command().toString()

    println("processBuilder = " + pbcmd)

    processBuilder.redirectErrorStream(redirectStream)

    val process = processBuilder.start()
    val reader  = new BufferedReader(new InputStreamReader(process.getInputStream()))

    println(reader.readLine())
    reader.close()
    process.waitFor()
  }

  def main(args :Array[String]) {
    println("start")
    spawn(className1, false)
    spawn(className2, false)
    println("end")
  }
}

【讨论】:

  • 这听起来很合理,但它对我不起作用。在我的 Eclipse ScalaTest 项目的默认包中复制代码会导致:className1 = O3 className2 = package1.O4 start processBuilder = [Z:\Coden\java\jre6x64\bin\java, -cp, Z:\Coden\WS- Scala-2.8\ScalaTest\bin, O3]
  • @Stefan K,我在 IntelliJ 9.0.2 上将上述内容作为脚本进行了测试,得到了“来自 O3 的你好”和“来自 O4 的你好”。两个waitFor调用都返回0。对于在类名中恢复了$后缀的运行,我从流中得到null,null,waitFor调用返回1、1。这可能是一个环境问题,也许你可以添加“echo”作为ProcessBuilder 构造函数调用的第一个参数,看看输出是什么,并可能复制并粘贴到 shell 中?
  • 用java,eclipse没有问题,这让我很困惑。以下是 ProcessBuilder 的所有构造函数参数的输出: Path: Z:\Coden\java\jre6x64\bin\java ClassP: Z:\Coden\WS-Scala-2.8\ScalaTest\bin className: O3 感谢您的耐心等待。跨度>
  • 上面的类路径条目看起来不标准你确定 scala-library.jar 在那个目录中吗?
  • 非常有用的 ProcessBuilder 示例行并找到 $JAVA_HOME/bin/java 路径和 cp arg 来运行它
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-03-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多