5

我正在尝试创建一个进程来修补我们当前的 java 应用程序,因此用户只需要下载差异而不是整个应用程序。我认为我不需要像二进制差异那样低级别,因为大多数 jar 文件都很小,所以替换整个 jar 文件并不是什么大不了的事(最多可能 5MB)。

是否有标准工具来确定哪些文件已更改并为它们生成补丁?我见过像 xdelta 和 vpatch 这样的工具,但我认为它们在二进制级别上工作。

我基本上想弄清楚 - 需要添加、替换或删除哪些文件。当我运行补丁时,它会检查软件的当前版本(从注册表设置)并确保补丁是正确的版本。如果是,它将进行必要的更改。听起来这对我自己来说并不太难实现,但我想知道其他人是否已经这样做了。如果这有什么不同,我将使用 NSIS 作为我的安装程序。

谢谢,

杰夫

4

4 回答 4

6

这样做时要小心——我建议根本不要这样做。

最大的问题是公共静态变量。它们实际上被编译到目标中,而不是被引用。这意味着即使 java 文件没有更改,也必须重新编译该类,否则您仍将引用旧值。

您还需要非常小心地更改方法签名——如果您更改方法签名并且不重新编译所有调用该方法的文件,您将得到一些非常微妙的错误——即使调用的 java 文件实际上不需要更改(例如,将参数从 int 更改为 long)。

如果您决定走这条路,请准备好在您无法复制的客户站点上出现一些非常难以调试的错误(通常没有痕迹或重要迹象,只是奇怪的行为,例如收到的数量与发送的数量不匹配)惹恼了顾客。

编辑(评论太长):

类文件的二进制差异可能会起作用,但我假设某种版本号或日期会被编译,并且每次编译都会无缘无故地改变一点,但这很容易测试。

您可以采取一些严格的开发实践,不使用公共最终静态(将它们设为私有),而不是每个更改方法签名(改为弃用),但我不相信我知道所有可能的问题,我只知道我们遇到的问题.

Jar 文件的二进制差异也是无用的,您必须区分类并将它们重新集成到 jar 中(听起来不容易跟踪)

你能单独打包你的资源然后把你的代码最小化吗?拉出字符串(适用于 i18n)——我想我只是想知道您是否可以修剪类文件以始终进行完整的构建/发布。

另一方面,Sun 似乎在制作与以前的 JRE 版本完全兼容的类文件方面做得很好,因此它们必须在某个地方有指导方针。

于 2010-09-17T20:08:46.423 回答
2

您可能想看看 Java WebStart 是否可以帮助您,因为它旨在完成您想做的那些事情。

我知道文档描述了如何创建和执行增量更新,但我们部署整个应用程序,因为它很少更改。然后是准备就绪时更新 JNLP 的问题。

于 2010-09-17T20:16:09.257 回答
1

它是如何部署的?

在本地网络上,我只是将所有内容作为 .class 文件保留在文件夹中。启动脚本使用 robocopy 或 rsync 从网络共享复制到本地。如果任何 .class 文件不同,则将其同步。如果没有,它不会同步。

对于非本地网络,我创建了自己的更新程序。它下载 md5sums 的文本文件并与本地文件进行比较。如果不同,它会从 http 下拉文件。

于 2010-09-18T02:01:34.763 回答
0

很久以前我们解决这个问题的方法是使用 Classpath 和 jar 文件。我们的应用程序是在一个 Jar 文件中构建的,它有一个启动器 Jar 文件。启动器类路径有一个 patch.jar,它在主 application.jar 之前被读入类路径。这意味着我们可以更新 patch.jar 以取代主应用程序中的任何类。

然而,这是很久以前的事了。您可能会更好地使用类似 Java Web Start 类型的方法,它提供更无缝的应用程序更新。

于 2010-09-17T20:04:48.117 回答