URLClassLoader + loadClass + вызвать метод main для автономного процесса? Джава - PullRequest
4 голосов
/ 08 января 2010

Я использую следующий метод для вызова класса внутри файла 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 (средство обновления клиента). С клиента а вы запускаете программу b (клиент)

Используя текущий код, спроецируйте a и все экземпляры проекта b будут использовать одно и то же пространство кучи. Я пытаюсь достичь состояния, когда все экземпляры проекта b являются автономными и не заботятся о том, завершен ли проект А. или нет.

1 Ответ

5 голосов
/ 08 января 2010

Да, и на самом деле это избавляет вас от выполнения этого процесса отражения в целом

Вам нужно будет использовать ProcessBuilder , чтобы запустить новый процесс на отдельной виртуальной машине.

Что-то вроде:

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

EDIT

- Будет ли это работать, если программа, выполняющая 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...