什么';这是在java代码中执行.jar的最佳方式

什么';这是在java代码中执行.jar的最佳方式,java,classloader,dynamic-class-loaders,Java,Classloader,Dynamic Class Loaders,我需要为java应用程序开发一个“启动器”。此启动器需要能够: 检查主应用程序是否是最新的 如果没有,请下载更新 运行此应用程序并自行终止 大概是这样的: public final class Launcher { public static void main(String[] args) throws Exception { String jarName = args[0]; if (jarHasUpdate(jarName) refreshJar(jarN

我需要为java应用程序开发一个“启动器”。此启动器需要能够:

  • 检查主应用程序是否是最新的
  • 如果没有,请下载更新
  • 运行此应用程序并自行终止
  • 大概是这样的:

    public final class Launcher {
      public static void main(String[] args) throws Exception {
        String jarName = args[0];
    
        if (jarHasUpdate(jarName)
          refreshJar(jarName);
    
        executeJar(jarName);
      }
    }
    
    有什么更好的方法来开发步骤3

    我正在尝试两种不同的方法:

    1-运行另一个Java实例

    使用代码:

    Runtime.getRuntime().exec("java -jar mainApp.jar");
    
    问题:在mainApp完成之前,启动器仍在运行

    2-在运行时使用ClassLoader加载.jar

    像这样:

    public final class Launcher {
        @SuppressWarnings({ "unchecked", "rawtypes" })
        public static void main(String[] args) throws Exception {
            if (args.length < 2) {
                System.out.println("Invalid number of arguments.");
                System.exit(1);
        }
    
        Refresh.refreshFile(args[0]);
    
        // args[0] .jar name
        // args[1] class with main function
        File file = new File(args[0]);
    
        try (URLClassLoader cl = new URLClassLoader(new URL[] { file.toURI().toURL() });) {
            Class cls = cl.loadClass(args[1]);
            Method method = cls.getDeclaredMethod("main", new Class[] { String[].class });
            Object params = new String[] {};
            method.invoke(cls, params);
            }
        }
    }
    
    公共最终类启动器{
    @SuppressWarnings({“unchecked”,“rawtypes”})
    公共静态void main(字符串[]args)引发异常{
    如果(参数长度<2){
    System.out.println(“参数数无效”);
    系统出口(1);
    }
    Refresh.Refresh文件(args[0]);
    //args[0]。jar名称
    //带有主函数的args[1]类
    File File=新文件(args[0]);
    try(URLClassLoader cl=newurlclassloader(newurl[]{file.toURI().toURL()});){
    类别cls=cl.loadClass(args[1]);
    方法Method=cls.getDeclaredMethod(“main”,新类[]{String[].Class});
    对象参数=新字符串[]{};
    调用(cls,params);
    }
    }
    }
    

    问题:如果“mainApp.jar”有依赖项,则不会加载该依赖项。

    为什么要这样做?您已经有了一个正在运行的Java进程;为什么不使用它?有没有一种方法可以使.jar自身更新?来详细说明@ElliottFrisch的问题:为什么不直接调用jar的
    main
    方法呢?而且,不,jar不能(安全地)自我更新;如果在覆盖原始jar后的任何时候都需要加载类,则会出现
    NoClassDefFoundError
    ,因为文件描述符将不再与原始文件匹配。您可以查看install4j。@MikeStrobel,在这种情况下,问题可能是:如何动态加载mainApp.jar并执行这个main方法?我正在尝试使用ClassLoader,但没有成功。