如何编写能够在运行时自我更新的Java应用程序?

如何编写能够在运行时自我更新的Java应用程序?,java,jar,auto-update,server-application,Java,Jar,Auto Update,Server Application,我想实现一个java应用程序(服务器应用程序),它可以从给定的url下载一个新版本(.jar文件),然后在运行时进行自我更新 做这件事的最好方法是什么?可能吗 我想应用程序可以下载一个新的.jar文件并启动它。但我应该如何进行交接,例如,知道新应用程序何时启动,然后退出。或者有更好的方法吗?这不一定是最好的方法,但可能对你有用 你可以编写一个引导应用程序(如果你玩过魔兽世界的话,那就是魔兽世界的启动器)。该引导程序负责检查更新 如果有更新,它会提供给用户,处理下载、安装等 如果应用程序是最新的

我想实现一个java应用程序(服务器应用程序),它可以从给定的url下载一个新版本(.jar文件),然后在运行时进行自我更新

做这件事的最好方法是什么?可能吗


我想应用程序可以下载一个新的.jar文件并启动它。但我应该如何进行交接,例如,知道新应用程序何时启动,然后退出。或者有更好的方法吗?

这不一定是最好的方法,但可能对你有用

你可以编写一个引导应用程序(如果你玩过魔兽世界的话,那就是魔兽世界的启动器)。该引导程序负责检查更新

  • 如果有更新,它会提供给用户,处理下载、安装等
  • 如果应用程序是最新的,它将允许用户启动应用程序
  • 或者,您可以允许用户启动应用程序,即使它不是最新的
这样,您就不必担心强制退出应用程序

如果您的应用程序是基于web的,并且如果客户机必须是最新的,那么您还可以在应用程序运行时进行版本检查。您可以在执行与服务器的正常通信(部分或所有调用)时,或同时执行这两种操作

对于我最近开发的一款产品,我们在发布时(没有启动程序,但在主窗口出现之前)和调用服务器时都进行了版本检查。当客户端过期时,我们依靠用户手动退出,但禁止对服务器执行任何操作


请注意,在打开主窗口之前,我不知道Java是否可以调用UI代码。我们使用的是C#/WPF。

受jEdit中类似机制的启发,我编写了一个Java应用程序,可以在运行时加载插件并立即开始使用它们。jEdit是开源的,所以你可以选择看看它是如何工作的


该解决方案使用自定义类加载器从jar加载文件。一旦它们被加载,您就可以从新jar调用一些方法,作为它的
main
方法。然后,棘手的部分是确保删除对旧代码的所有引用,以便可以对其进行垃圾收集。我不是这方面的专家,我已经做到了,但这并不容易。

解决方案的基本结构如下:

  • 有一个主循环负责反复加载应用程序的最新版本(如果需要)并启动它

  • 应用程序会执行它的操作,但会定期检查下载URL。如果它检测到一个新版本,它将退出到启动器

有很多方法可以实现这一点。例如:

  • 启动器可以是一个包装器脚本或二进制应用程序,它启动一个新的JVM,从被替换的JAR文件运行应用程序

  • 启动器可以是一个Java应用程序,它为新JAR创建一个类加载器,加载一个entrypoint类并对其调用一些方法。如果您这样做,您必须注意classloader存储泄漏,但这并不困难。(您只需要确保在重新启动后,没有从JAR加载类的对象是可访问的。)

外部包装方法的优点是:

  • 你只需要一个罐子
  • 您可以替换整个Java应用程序
  • 应用程序等创建的任何辅助线程将在没有特殊关闭逻辑的情况下消失,并且
  • 您还可以处理从应用程序崩溃中恢复等问题
第二种方法需要两个JAR,但具有以下优点:

  • 该解决方案是纯Java和可移植的
  • 转换会更快,而且
  • 您可以更轻松地在重启过程中保持状态(模泄漏问题)
“最佳”方式取决于您的具体要求

还应指出的是:

  • 自动更新存在安全风险。通常,如果提供更新的服务器受损,或者提供更新的机制容易受到攻击,则自动更新可能导致客户端受损

  • 向客户推送对客户造成损害的更新可能会有法律风险,并会对您的业务声誉造成风险


如果你能找到一种避免重新发明轮子的方法,那就好了。有关建议,请参见其他答案

  • 第一种方法:使用tomcat及其部署工具
  • 第二种方法:将应用程序分为两部分(功能部分和更新部分),让更新部分替换功能部分
  • 第三种方式:在您的服务器应用程序中,只需下载新版本,然后旧版本释放绑定端口,然后旧版本运行新版本(启动进程),然后旧版本在应用程序端口向新版本发送删除旧版本的请求,旧版本终止,新版本删除旧版本。这样地:

  • 如果您使用插件构建应用程序,则可以使用来获得此问题的现成解决方案。这将要求服务器在更新后重新启动自身。

    这是一个已知的问题,我建议不要重新发明轮子-不要编写自己的黑客程序,只使用其他人已经完成的程序

    您需要考虑两种情况:

  • 应用程序需要能够自我更新,即使在更新期间也能保持运行(服务器应用程序、嵌入式应用程序)。跟奥斯基一起去:或者

  • 应用程序是一个桌面应用程序,具有安装程序。有许多安装程序具有更新选项。检查


  • 我目前正在开发一个JAVA Linux守护程序,并且还需要实现一个自动更新机制。我想将我的应用程序限制为一个jar文件,并提出了一个简单的解决方案:

    打包更新程序应用程序i