2010-07-16 4 views
3

J'écris une application de réseau, où chaque client a un Singleton ClientManager. Pour tester, je voudrais créer plusieurs clients (chacun dans leur propre VM/processus) sans démarrer le programme à la main n fois.ProcessBuilder - Démarrer un autre processus/JVM - HowTo?

Les deux questions sur StackOverflow décrivent déjà comment à faire suivants:

Mon code est basé sur ceux-ci, mais il ne fonctionne pas:

  • Le programme principal ne se poursuit pas après l'appel de spawn.
  • Le code généré n'est pas exécuté.

Voici le code complet en utilisant ProcessBuilder:

public class NewVM { 
    static class HelloWorld2 { 
    public static void main(String[] args) { 
     System.out.println("Hello World"); 
     System.err.println("Hello World 2"); 
    } 
    } 
    public static void main(String[] args) throws Exception { 
    startSecondJVM(HelloWorld2.class, true); 
    startSecondJVM(HelloWorld2.class, false); 
    System.out.println("Main"); 
    } 
    public static void startSecondJVM(Class<? extends Object> clazz, boolean redirectStream) throws Exception { 
    System.out.println(clazz.getCanonicalName()); 
    String separator = System.getProperty("file.separator"); 
    String classpath = System.getProperty("java.class.path"); 
    String path = System.getProperty("java.home") 
      + separator + "bin" + separator + "java"; 
    ProcessBuilder processBuilder = 
      new ProcessBuilder(path, "-cp", 
      classpath, 
      clazz.getCanonicalName()); 
    processBuilder.redirectErrorStream(redirectStream); 
    Process process = processBuilder.start(); 
    process.waitFor(); 
    System.out.println("Fin"); 
    } 
} 

Qu'est-ce que je fais mal ???

BTW:

  • J'utilise Eclipse. Le problème de Singleton est un exemple simplifié. S'il vous plaît faire pas suggère de créer une usine.

Solution: HelloWorld2 ne doit pas être une classe interne.

Répondre

2

Je vous suggère de faire de HelloWorld2 une classe de haut niveau. Il semble que Java attend une classe de haut niveau.

C'est le code que j'ai essayé.

class Main 
{ 
    static class Main2 
    { 
     public static void main (String [ ] args) 
     { 
      System . out . println ("YES!!!!!!!!!!!") ; 
     } 
    } 

    public static void main (String [ ] args) 
    { 
     System . out . println (Main2 . class . getCanonicalName ()) ; 
     System . out . println (Main2 . class . getName ()) ; 
    } 
} 

class Main3 
{ 
    public static void main (String [ ] args) 
    { 
     System . out . println ("YES!!!!!!!!!!!") ; 
    } 
} 
  1. getCanonicalName et getName retour des noms différents. Lequel a raison? Ils ont tous les deux tort.
  2. Main3 fonctionne.
1

Je pense que je vois un correctif pour une partie du problème: process.waitFor() empêche le contrôle de retourner à main() avant la fin du sous-processus.

Pour comprendre pourquoi votre processus généré ne démarre pas, je recommande d'imprimer tous les arguments au constructeur ProcessBuilder et de vérifier qu'une machine virtuelle appelée manuellement avec ces arguments réussit. En particulier, vous avez besoin que ce nom de classe soit le nom d'une classe ayant un static void main(String[]).