2010-07-21 18 views
2

J'ai déjà géré pour démarrer une autre machine virtuelle en Java. Voir ProcessBuilder - Start another process/JVM - HowTo?ProcessBuilder - Démarrer un autre processus/JVM dans Scala - HowTo?

Pour une raison quelconque, je n'arrive pas à faire la même chose avec Scala. Voici mon 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") 
    } 
} 

J'ai essayé de définir le principal dans un objet et en classe. Les deux dans le même fichier .scala ou dans un fichier séparé.

Qu'est-ce que je fais mal?

+0

Vous devriez donner plus de détails sur ce que vous avez fait après avoir écrit ce code: quels outils/commandes avez-vous utilisés? Quel était le résultat? –

+0

Les détails sont les mêmes que dans ma question java. classe O3 { def principaux (args: Array [String]) { println ("O3") }} –

Répondre

4

Le problème semble être que le nom de classe d'un objet a un suffixe '$'.

Si vous supprimez ce suffixe, la ligne d'appel Java déclenchée à partir de ProcessBuilder fonctionne.

J'ai piraté quelque chose ci-dessous pour montrer quelques cas de test. Je ne suis pas encore sûr pourquoi c'est le cas mais au moins cela fournit une solution de contournement.

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

Cela semble raisonnable, mais cela ne fonctionne pas pour moi. Copie de votre code dans le package par défaut de mes résultats du projet Eclipse ScalaTest dans: className1 = O3 className2 = package1.O4 commencer ProcessBuilder = [Z: \ Coden \ java \ jre6x64 \ bin \ java, -cp, Z: \ Coden \ WS-Scala-2.8 \ ScalaTest \ bin, O3] –

+0

@Stefan K, j'ai testé ce qui précède comme un script sur IntelliJ 9.0.2 et j'ai reçu "bonjour de O3" et "bonjour de O4". Les deux appels waitFor retournés 0. Pour une exécution avec le suffixe $ restauré dans le nom de la classe, je reçois null, null des flux et les appels waitFor retour 1, 1. Cela pourrait être un problème environnemental, peut-être que vous pourriez ajouter "echo" comme le premier paramètre à l'appel du constructeur ProcessBuilder et voir ce qui est sortie et éventuellement copier et coller dans un shell? –

+0

Avec java, il n'y a pas de problème avec eclipse, ça m'embrouille. Voici la sortie de tous les paramètres de constructeur de ProcessBuilder: Chemin d'accès: Z: \ Coden \ java \ jre6x64 \ bin \ java ClassP: Z: \ Coden \ WS-Scala-2.8 \ ScalaTest \ bin className: O3 Merci pour votre la patience. –