【问题标题】:Update java desktop app更新 java 桌面应用程序
【发布时间】:2015-03-24 08:41:03
【问题描述】:

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

我想到的一个解决方案是我可以在我的主 jar 中放置一个 jar,并在启动更新过程时提取第二个 jar,它将显示图像和进度条,并且也将替换旧的 main jar 和一个新的主 jar。 我的问题是这是否可能,我该怎么做。 我对 java 和 java 打包没有太多经验,所以如果你有任何示例或链接,对我有很大帮助。

非常感谢。 R.

【问题讨论】:

  • 请务必让我们知道您是否成功
  • 您确定在不停止应用程序的情况下更新“主 UI”有意义吗?我曾经创建了一个支持许多插件的大型应用程序;并且每个插件都可以“即时”更新。但是为了更新您的“主 UI”......无论如何,您都必须“停止它”(因为您必须丢弃用于加载 JAR 内容的类加载器)。含义:无论如何,用户都会遇到“中断”;那么为什么要努力卸载一个 JAR,加载一个新的(带有进度条)?停止应用程序并拥有一个独立的“升级应用程序”会容易得多。
  • 您可以考虑某种启动主应用程序的“启动器”应用程序。启动器可以在启动之前更新主应用程序。
  • 思路是内jar必须从主jar中提取出来,主jar会停止运行,内jar会显示进度条和图片。此外,内部 jar 将替换主 jar(从主 jar 上的另一个位置复制一个新 jar),之后它将启动新的主 jar 并退出。很难实现。我必须在主罐运行时提取内罐。我该怎么做?

标签: java desktop-application executable-jar auto-update


【解决方案1】:

按下 UPDATE 按钮时运行此代码..

if(Desktop.isDesktopSupported()){
            try {
                Desktop.getDesktop().open(new File("update.jar"));
                System.exit(0);
            } catch (IOException ex) {                
            }            
        }

这将打开 update.jar 并关闭 ma​​in.jar。现在从 update.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"));
    }

【讨论】:

  • 你需要等待 update.jar 直到终止 main.jar
【解决方案2】:

您可以有一个启动 jar 来检查更新并从主 jar 启动应用程序。

它将显示启动标志,一个图像,标准 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
    }

正如您所见,主 jar 不能过早加载,可能不完全在类路径上,因此使用单独的 ClassLoader。可能对主 jar on 入门应用程序的类路径以及使用 Class.forName("mainjar.MainApp") 进行同样的操作。 Class-Path 可以在 META-INF/MANIFEST.MF 中指定。

辅助 jar 可能驻留在 lib/ 目录中。

对于那些想要更模块化、面向服务、可更新的应用程序的读者,可以制作一个 OSGi 应用程序,一个包 (=jars) 的容器,它提供可交换的服务和生命周期控制。

【讨论】:

    猜你喜欢
    • 2010-09-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-12
    • 2010-11-26
    • 1970-01-01
    • 2011-02-15
    相关资源
    最近更新 更多