2010-01-08 19 views
4

J'utilise la méthode suivante pour appeler une classe à l'intérieur d'un fichier jar:URLClassLoader + loadClass + appelle la méthode principale sur un processus autonome? Java

invokeClass("path.to.classfile", new String[] {}); 

public static void invokeClass(String name, String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, MalformedURLException { 
    File f = new File(System.getProperty("user.home") + File.separator + ".myapplication"+File.separator+"myjar.jar"); 

    URLClassLoader u = new URLClassLoader(new URL[]{f.toURI().toURL()}); 
    Class c = u.loadClass(name); 
     Method m = c.getMethod("main", new Class[] { args.getClass() }); 
     m.setAccessible(true); 
     int mods = m.getModifiers(); 
     if (m.getReturnType() != void.class || !Modifier.isStatic(mods) || !Modifier.isPublic(mods)) { 
     throw new NoSuchMethodException("main"); 
     } 
     try { 
     m.invoke(null, new Object[] { args }); 
     } catch (IllegalAccessException e) { 

     } 
} 

Est-il possible d'invoquer cela sur un processus distinct? Donc, l'application en cours d'exécution et la nouvelle application invoquée n'ont rien en commun? Situation: Vous lancez le programme a (mise à jour du client). A partir du client a, vous lancez le programme b (client)

Avec le code actuel, projetez ET toutes les instances du projet b partagent le même espace de segment. J'essaie de parvenir à un état où toutes les instances du projet b sont autonomes et ne se soucient pas si le projet A est terminé ou non.

Répondre

5

Oui, et en fait que vous évite d'exécuter ce processus de réflexion tout à fait

Vous aurez besoin d'utiliser ProcessBuilder pour lancer un nouveau processus dans une machine virtuelle séparée.

Quelque chose comme:

ProcessBuilder pb = new ProcessBuilder("java", "-jar", f.getAbsolutePath()); 
Process p = pb.start(); 

EDIT

- Est-ce que le travail si le programme qui fait pb.start() se termine?

- Est-ce que le travail si la variable d'environnement java est pas définie (par exemple Mac OS X?) [Ne peut pas tester sur mac os x]

Il fait. Jetez un oeil à cette vidéo:

http://img33.imageshack.us/img33/8380/capturadepantalla201001s.png

Le code source (importations omises):

// MainApp.java 

public class MainApp { 
    public static void main(String [] args) throws IOException { 
     JFrame frame = new JFrame("MainApp"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.add(new JLabel("<html><font size='48'>Main App Running</font><html>")); 
     frame.pack(); 
     frame.setLocationRelativeTo(null); 
     frame.setVisible(true); 
     launchSeparateProcess(); 
     frame.addWindowListener(new WindowAdapter() { 
      public void windowClosing(WindowEvent e){ 
       System.out.println("MainAppp finished"); 
      } 
     }); 
    } 
    private static void launchSeparateProcess() throws IOException { 
     File f = new File("./yourjar.jar"); 
     ProcessBuilder pb = new ProcessBuilder("java", "-jar", f.getAbsolutePath()); 
     Process p = pb.start(); 
    } 
}  

//-- Updater.jar 
public class Updater { 
    public static void main(String [] args) { 
     JFrame frame = new JFrame(); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.add(new JLabel("<html><font size='78'>Updating....</font></html>")); 
     frame.pack(); 
     frame.setVisible(true); 
    } 
} 
//--manifest.mf 
Main-Class: Updater 
+0

cela fonctionnera si le programme qui ne pb.start() se termine? – TofuBeer

+1

Theres est seulement une façon de savoir ... – OscarRyz

+0

Cela fonctionnera-t-il si la variable d'environnement java n'est pas définie (par exemple Mac OS X?) [Ne peut pas tester sur mac os x] – Peeter