ProcessBuilder - Start another process / JVM in Scala - HowTo?
I already handled to start another VM in Java. See ProcessBuilder - Start another process / JVM - HowTo?
For some reason, I can't manage to do the same in Scala. Here's my 开发者_高级运维code
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")
}
}
I've tried to define the main in an object and in class. Both within the same .scala file or within a separate one.
What am I doing wrong?
The issue seems to be that the class name for an object has a '$' suffix.
If you strip off that suffix, the Java invocation line triggered from ProcessBuilder works.
I've hacked something below to show a couple of test cases. I'm not yet sure yet why this is the case but at least it provides a workaround.
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")
}
}
精彩评论