URLClassLoader+;loadClass+;在独立进程上调用main方法?JAVA

URLClassLoader+;loadClass+;在独立进程上调用main方法?JAVA,java,process,invoke,urlclassloader,Java,Process,Invoke,Urlclassloader,我使用以下方法调用jar文件中的类: invokeClass("path.to.classfile", new String[] {}); public static void invokeClass(String name, String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, MalformedURLException { File f = ne

我使用以下方法调用jar文件中的类:

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) {

      }
}
是否可以在单独的流程中调用此功能?那么运行中的应用程序和新调用的应用程序没有任何共同之处

情况:您启动程序a(客户端更新程序)。从客户端a启动程序b(客户端)


对于当前代码,项目a和项目b的所有实例共享相同的堆空间。我试图达到这样一种状态,即项目b的所有实例都是独立的,并且不关心项目a是否终止。

是的,实际上这使您不必执行整个反射过程

您需要使用在单独的虚拟机中启动新进程

比如:

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

-如果执行pb.start()的程序终止,这会起作用吗


-如果没有设置java环境变量(例如Mac OS X?)[无法在Mac OS X上测试],这会起作用吗

是的。请看这段视频:

源代码(导入省略):

//MainApp.java
公共类MainApp{
公共静态void main(字符串[]args)引发IOException{
JFrame=新JFrame(“MainApp”);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(新的JLabel(“主应用程序运行”);
frame.pack();
frame.setLocationRelativeTo(空);
frame.setVisible(true);
启动分离进程();
frame.addWindowListener(新的WindowAdapter(){
公共无效窗口关闭(WindowEvent e){
System.out.println(“MainAppp完成”);
}
});
}
私有静态void launchSeparateProcess()引发IOException{
文件f=新文件(“./yourjar.jar”);
ProcessBuilder pb=新的ProcessBuilder(“java”,“-jar”,f.getAbsolutePath());
进程p=pb.start();
}
}    
//--Updater.jar
公共类更新程序{
公共静态void main(字符串[]args){
JFrame=新JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(新的JLabel(“更新…”);
frame.pack();
frame.setVisible(true);
}
}
//--manifest.mf
主类:更新程序

如果执行pb.start()的程序终止,这是否有效?如果没有设置java环境变量(例如Mac OS X),这是否有效?[无法在Mac OS X上测试]
// 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