【问题标题】:URLClassLoader + loadClass + invoke main method on a standalone process? JavaURLClassLoader + loadClass + 在独立进程上调用 main 方法?爪哇
【发布时间】:2010-01-08 01:33:28
【问题描述】:

我正在使用以下方法来调用 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 是否终止。

【问题讨论】:

    标签: java process invoke urlclassloader


    【解决方案1】:

    是的,实际上这使您免于完全执行反射过程

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

    类似:

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

    编辑

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

    - 如果未设置 java 环境变量(例如 Mac OS X?)[无法在 mac os x 上测试]

    ,这是否有效

    确实如此。看看这个视频:

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

    源代码(省略导入):

    // 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
    

    【讨论】:

    • 如果执行 pb.start() 的程序终止,这会起作用吗?
    • 如果没有设置 java 环境变量,这会起作用吗(例如 Mac OS X?)[无法在 mac os x 上测试]
    猜你喜欢
    • 1970-01-01
    • 2015-02-05
    • 2020-08-08
    • 1970-01-01
    • 2015-05-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-13
    相关资源
    最近更新 更多