2010-07-21 3 views
2

Java에서 다른 VM을 시작하기 위해 이미 처리했습니다. ProcessBuilder - Start another process/JVM - HowTo?ProcessBuilder - 스칼라에서 다른 프로세스/JVM 시작 - HowTo?

어떤 이유로 스칼라에서 동일한 작업을 수행 할 수 없습니다. 는 여기에 내가 객체와 클래스의 주를 정의하기 위해 노력했습니다

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

내 코드입니다. 둘 다 동일한 .scala 파일 내에서 또는 별도의 파일 내에서.

내가 뭘 잘못하고 있니?

+0

해당 코드를 작성한 후에 수행 한 작업에 대한 자세한 정보를 제공해야합니다. 어떤 도구/명령을 사용 했습니까? 그 결과는 무엇입니까? –

+0

세부 사항은 내 Java 질문과 동일합니다. O3 { def main (args : Array [String]) { println ("O3") } } –

답변

4

개체의 클래스 이름에 '$'접미사가있는 것 같습니다.

접미어를 제거하면 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") 
    } 
} 
+0

이것은 합리적인 것 같지만 저에게는 적합하지 않습니다. 내 이클립스 ScalaTest 프로젝트 결과의 기본 패키지에 코드를 복사 : className1 = O3 className2 = package1.O4 시작 ProcessBuilder를 = [Z : \ CODEN \ 자바 \ jre6x64의 \ 빈 \ 자바, -cp, Z : \ Coden \ WS-Scala-2.8 \ ScalaTest \ bin, O3] –

+0

@Stefan K, 위의 스크립트를 IntelliJ 9.0.2에서 스크립트로 테스트했으며 "hello from O3"및 "hello from O4"를 받았습니다. waitFor 호출은 모두 0을 반환했습니다. $ 접미어가 클래스 이름에 복원되어 실행되면 스트림에서 null이 반환되고 waitFor 호출은 1을 반환합니다. 환경 문제 일 수 있습니다. 아마도 "echo"를 다음과 같이 추가 할 수 있습니다. ProcessBuilder 생성자에 대한 첫 번째 매개 변수를 호출하여 출력 내용을 확인하고 셸에 복사하여 붙여 넣을 수 있습니까? –

+0

자바에서는 일식에 문제가 없으므로 혼란 스럽습니다. 다음은 ProcessBuilder의 모든 생성자 매개 변수의 출력입니다. 경로 : Z : \ Coden \ java \ jre6x64 \ bin \ java ClassP : Z : \ Coden \ WS- Scala-2.8 \ ScalaTest \ bin className : O3 인내. –