Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/328.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
更新java桌面应用程序_Java_Desktop Application_Executable Jar_Auto Update - Fatal编程技术网

更新java桌面应用程序

更新java桌面应用程序,java,desktop-application,executable-jar,auto-update,Java,Desktop Application,Executable Jar,Auto Update,我正在尝试开发一个模块,可以更新我正在运行的Java桌面应用程序。 问题是,我必须用另一个jar替换实际运行的jar,同时显示一个图像和一个进度条以及更新过程的剩余时间 我考虑的一个解决方案是,我可以在我的主jar中放置一个jar,在启动更新过程时,提取第二个jar,它将显示图像和进程栏,还将用一个新的主jar替换旧的主jar。 我的问题是,这是否可能,我如何才能做到。 我在java和java打包方面没有很多经验,因此如果您有任何示例或链接,这将对我有很大帮助 多谢各位。 R.您可以拥有一个初学

我正在尝试开发一个模块,可以更新我正在运行的Java桌面应用程序。 问题是,我必须用另一个jar替换实际运行的jar,同时显示一个图像和一个进度条以及更新过程的剩余时间

我考虑的一个解决方案是,我可以在我的主jar中放置一个jar,在启动更新过程时,提取第二个jar,它将显示图像和进程栏,还将用一个新的主jar替换旧的主jar。 我的问题是,这是否可能,我如何才能做到。 我在java和java打包方面没有很多经验,因此如果您有任何示例或链接,这将对我有很大帮助

多谢各位。
R.

您可以拥有一个初学者jar,用于检查更新并从主jar启动应用程序

它将显示start徽标,一个标准java可以在启动时显示的图像。 start0er还可以用另一种界面语言重新启动应用程序

package starter;
...
public class StarterApp {
    public static void main(String[] args) {
        String workDir = System.getProperty("user.dir");
        Path mainJar = Paths.get(workDir + "...");
        Path nextMainJar = Paths.get(workDir + "...");
        if (Files.exists(nextMainJar)) {
            Files.copy(nextMainJar, mainJar, StandardCopyAction.REPLACE_EXISTING);
        }
        URLClassLoader classLoader = new URLClassLoader(new URL[] {mainJar.toURL()});
        Class<?> appClass = classLoader.find("mainjar.MainApp");
        ... instantiate the app
    }
包装启动器;
...
公共类应用程序{
公共静态void main(字符串[]args){
字符串workDir=System.getProperty(“user.dir”);
Path mainJar=Path.get(workDir+“…”);
Path nextMainJar=Path.get(workDir+“…”);
if(Files.exists(nextMainJar)){
复制(nextMainJar、mainJar、StandardCopyAction.REPLACE_现有);
}
URLClassLoader classLoader=新的URLClassLoader(新的URL[]{mainJar.toURL()});
类appClass=classLoader.find(“mainjar.MainApp”);
…实例化应用程序
}
正如您所看到的,主jar不能过早加载,可能不完全在类路径上,因此需要使用单独的类加载器。对于starter应用程序的类路径上的主jar,也可以使用
class.forName(“mainjar.MainApp”)进行加载
。可以在META-INF/MANIFEST.MF中指定类路径

secundary jar可以驻留在lib/目录中


对于那些想要更多模块化、面向服务、可更新应用程序的读者,可以制作一个OSGi应用程序,一个捆绑包(=JAR)的容器,提供可交换的服务和终身控制。

当按下更新按钮时运行此代码

if(Desktop.isDesktopSupported()){
            try {
                Desktop.getDesktop().open(new File("update.jar"));
                System.exit(0);
            } catch (IOException ex) {                
            }            
        }
这将打开update.jar并关闭main.jar

 if(isUpdateVersionAvailable()) { //first check update from database
      try{
          Thread.sleep(5000);
       } catch(Exception e){
          e.printStackTrace();
       }
       if(copyMainJarFileFromServer()){ //copy newMain.jar from server and paste
            new File("main.jar").delete();
            rename(new File("newMain.jar"));
        }
    }

    boolean isUpdateVersionAvailable() {
              //todo
    }
    boolean copyMainJarFileFromServer() {
              //todo
    }
    void rename(File file){
     file.renameTo(new File("main.jar"));
    }

请务必让我们知道您是否成功,您是否确定在不停止应用程序的情况下更新“主UI”是有意义的?我曾经创建了一个支持多个插件的大型应用程序;每个插件都可以“动态”更新。但为了更新“主UI”…您无论如何都必须“停止”(因为你将不得不放弃用来加载JAR内容的类加载器)。意思是:用户无论如何都会经历一次“中断”;那么为什么要卸载一个JAR,加载一个新的(带有进度条)?停止应用程序并拥有一个独立的“升级应用程序”会容易得多。你可以考虑一些“启动器”-启动主应用程序的应用程序。启动器可以在启动主应用程序之前更新主应用程序。其想法是,必须从主jar中提取内部jar,主jar将停止运行,并且内部jar将显示进度条和图像。此外,内部jar将替换主jar(从主jar上的另一个位置复制一个新的jar),然后它将启动新的主jar并退出。很难实现。我必须在主jar运行时提取内部jar。我如何才能做到这一点?您需要等待update.jar,直到终止main.jar