如何使 Java 应用程序自我更新?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10239936/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I make a Java app self-update?
提问by Ryan Stewart
Problem: I have a standalone Java app (henceforth known as "the agent") that runs as a service on internal company servers. It acts as a remote agent for some central servers. As the agent gets deployed in more places, managing them is getting more complicated. Specifically: pushing updates is painful because it's a fairly manual process, and getting access to the logs and other info about the environments where the agents are running is problematic, making debugging difficult. The servers under discussion are headless and unattended, meaning that this has to be a fully automated process with no manual intervention, hence Java Web Start isn't a viable solution.
问题:我有一个独立的 Java 应用程序(以下称为“代理”),它作为服务在公司内部服务器上运行。它充当某些中央服务器的远程代理。随着代理部署在更多地方,管理它们变得越来越复杂。具体来说:推送更新是痛苦的,因为它是一个相当手动的过程,并且获取有关代理运行的环境的日志和其他信息是有问题的,使得调试变得困难。讨论中的服务器是无头和无人值守的,这意味着这必须是一个没有人工干预的完全自动化的过程,因此Java Web Start 不是一个可行的解决方案。
Proposed solution: Make the agent phone home (to the central servers) periodically to provide agent status and check for updates.
建议的解决方案:定期让代理电话回家(到中央服务器)以提供代理状态并检查更新。
I'm open to other suggested solutions to the problem, but I've already got a working prototype for the "status and self-updates" idea, which is what this question is focused on.
我对这个问题的其他建议解决方案持开放态度,但我已经有了一个“状态和自我更新”想法的工作原型,这就是这个问题的重点。
What I came up with is actually a separate project that acts as a wrapper for the agent. The wrapper periodically calls the central server via HTTP to check for an updated version of the agent. Upon finding an update, it downloads the new version, shuts down the running agent, and starts the new one. If that seems like an odd or roundabout solution, here are a few other considerations/constraints worth noting:
我想出的实际上是一个单独的项目,它充当代理的包装器。包装器通过 HTTP 定期调用中央服务器以检查代理的更新版本。找到更新后,它会下载新版本,关闭正在运行的代理,然后启动新的代理。如果这看起来像是一个奇怪或迂回的解决方案,这里有一些其他注意事项/约束值得注意:
- When the wrapper gets a new version of the agent, there may be new JAR dependencies, meaning class path changes, meaning I probably want to spawn a separate Java process instead of fiddling with ClassLoaders and running the risk of a permanent generation memory leak, which would require manual intervention--exactly what I'm trying to get away from. This is why I ended up with a separate, "wrapper" process to manage the agent updates in my prototype.
- Some servers where the agents are deployed are resource-limited, so any solution needs to be low on CPU and memory usage. That makes me want a solution that doesn't involve spinning up a new JVM and is a stroke against having a separate wrapper process.
- The agent is already deployed to both Windows and RHEL servers, so the solution must be cross-platform, though I wouldn't have a problem duplicating a reasonable amount of the process in batch and bash scripts to get things rolling.
- 当包装器获得新版本的代理时,可能会有新的 JAR 依赖项,这意味着类路径发生变化,这意味着我可能想要生成一个单独的 Java 进程,而不是摆弄类加载器并冒着永久代内存泄漏的风险,这需要人工干预——正是我想要摆脱的。这就是为什么我最终使用一个单独的“包装器”流程来管理原型中的代理更新。
- 部署代理的某些服务器资源有限,因此任何解决方案都需要降低 CPU 和内存使用率。这让我想要一个不涉及启动新 JVM 的解决方案,并且反对拥有单独的包装进程。
- 该代理已经部署到 Windows 和 RHEL 服务器,因此该解决方案必须是跨平台的,尽管我不会在批处理和 bash 脚本中复制合理数量的过程以使事情顺利进行。
Question: As stated, I want to know how to make a self-updating Java app. More specifically, are there any frameworks/libraries out there that would help me with this? Can someone with experience in this area give me some pointers?
问题:如上所述,我想知道如何制作一个自我更新的 Java 应用程序。更具体地说,是否有任何框架/库可以帮助我解决这个问题?有这方面经验的人能给我一些指点吗?
回答by Miquel
If your application is OSGi based, you could let OSGi handle bundle updates for you. It is similar to the wrapper approach you suggest, in that the OSGi container itself is "the wrapper" and some of it won't be updated. Here's a discussion on this
如果您的应用程序基于 OSGi,您可以让 OSGi 为您处理包更新。它类似于您建议的包装器方法,因为 OSGi 容器本身是“包装器”,其中一些不会更新。这是关于这个的讨论
回答by Miquel
回答by Amr Lotfy
No need for wrapper (save memory) or java web start (adds more restrictions on your application), simply let a thread in you application check periodically for updates (e.g. from cloud) and download updates if available, then code these two calls in you application:
不需要包装器(节省内存)或 java web start(对您的应用程序添加更多限制),只需让应用程序中的线程定期检查更新(例如来自云)并下载更新(如果可用),然后在您中编码这两个调用应用:
- launch a shell script (
.sh
or.cmd
) to update your artifacts and launch your application after few seconds pause in the script(to avoid having two instances of your application at the same time). - Terminate your application (first instance)
- 启动一个 shell 脚本(
.sh
或.cmd
)来更新你的工件并在脚本中暂停几秒钟后启动你的应用程序(以避免同时有两个应用程序实例)。 - 终止您的应用程序(一审)
The script can overwrite needed artifacts and re-launch your application.
该脚本可以覆盖所需的工件并重新启动您的应用程序。
enjoy !
请享用 !
回答by Cheeso
Have a look at Java Web Start.
看看 Java Web Start。
It is technology that's been part of Java since... 1.5? maybe 1.4? and allows deployment and install of standalone Java-based apps through a web browswer. It also enables you to always run the latest app.
它是自... 1.5 以来一直是 Java 的一部分的技术?也许1.4?并允许通过网络浏览器部署和安装独立的基于 Java 的应用程序。它还使您能够始终运行最新的应用程序。
http://www.oracle.com/technetwork/java/javase/overview-137531.html
http://www.oracle.com/technetwork/java/javase/overview-137531.html
http://en.wikipedia.org/wiki/JNLP#Java_Network_Launching_Protocol_.28JNLP.29
http://en.wikipedia.org/wiki/JNLP#Java_Network_Launching_Protocol_.28JNLP.29
also see this question: What's the best way to add a self-update feature to a Java Swing application?