ProcessBuilder - Запустить другой процесс / JVM в Scala - Как? - PullRequest
2 голосов
/ 21 июля 2010

Я уже обработал запуск другой виртуальной машины на Java.См. ProcessBuilder - Запуск другого процесса / 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 или в отдельном.

Что я делаю не так?

1 Ответ

4 голосов
/ 21 июля 2010

Кажется, проблема в том, что имя класса для объекта имеет суффикс '$'.

Если вы удалите этот суффикс, строка вызова Java, запущенная из ProcessBuilder, будет работать.Я взломал что-то ниже, чтобы показать пару тестов.Я еще не уверен, почему это так, но, по крайней мере, это обеспечивает обходной путь.

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")
  }
}
...