【问题标题】:Is decompression of pack200 deterministic and identical on all platforms?pack200 的解压是否在所有平台上都具有确定性和相同性?
【发布时间】:2011-09-03 08:21:08
【问题描述】:

我想将我的 20 罐应用程序作为 pack200 文件分发,但我还需要提供文件校验和以进行验证。

因为我是偏执狂(谢谢你,JWS),我还想对解压文件进行校验。

pack200 的解压是否确定并在所有平台上给出相同的结果(Win/Mac/Linux 跨 32/64 位)?

换句话说,我可以在一台计算机上解压缩文件,计算它们的校验和,并期望它们在其他计算机上解压缩时始终相同吗?

编辑:感谢 cmets。我正在寻找一些硬性规范来确认或否认这一点。

做出假设(即使基于在几台机器上的测试)意味着风险。

实现可能因平台和 Java 版本而异。即使是相同的实现也会给出不同的结果(考虑 ZIP 目录中项目的顺序?)。这就是为什么我问它是否对于所有平台和 Java 版本都相同 AND 确定性。


如果无法确认或拒绝,那么这个后续问题如何。如何验证解压后的 jar 是否有效?想想半成品文件,伽马射线破坏文件中的单个位等等。

【问题讨论】:

  • Jar 中有每个条目的校验和。如果没有在所有平台上解压相同的内容,它们将被损坏并且应该被检测到。
  • @Peter 谢谢。这是否意味着整个罐子总是相同的?
  • 你试过在不同的机器和不同的java版本上解压同一个pack200存档吗?
  • pack200 本身就是一个 Java 应用程序,应该在所有平台上运行相同。很难想象为什么它会有依赖于平台的行为。我会假设它是相同的,除非你知道。
  • @tulskiy 我在这里寻找一些硬参考。我可以在 5 个系统上对其进行测试,但不一定普遍可靠。我的用户可能在第 6 个未经测试的系统上给出不同的结果,或者不同版本的 Java 可能会以不同的方式工作......所以我需要一些硬规范来说明“是的,它总是相同的”。

标签: java


【解决方案1】:

想想that's 你在找什么。

...但是,对于任何给定的 Pack200 存档,每个解压缩器都需要为传输的每个类文件生成特定的字节图像。这个要求放在解压缩器上,以便使压缩器可以传输信息,例如消息摘要,这些信息与传输的类文件的最终字节内容有关。本节描述了对每个解压缩器的限制,这些限制使其输出文件的按字节内容成为其输入的明确定义的函数。

这意味着你可以在这里做你想做的事。 JNF/Pack200 的工作原理是取出跨类共享的常量并智能压缩 .class 文件 - 但标准的这一部分表示,虽然可以通过多种方式重建类文件,但这将导致无法验证这些带有摘要的文件。为了避免这个问题,Pack200 明确指定了解码应该如何工作 - 因此,虽然输出 .class 文件可能与输入 .class 文件不同,但每个 Pack200 解压缩器的输出 .class 文件都将匹配所有其他 Pack200 解压缩器的输出 .class 文件。

所以你最好的办法是用 Pack200 打包它们,解压它们,然后执行 MD5 或类似的摘要算法,并使用它来验证解压文件。

希望能回答您的问题!

【讨论】:

  • 太好了,谢谢。 JAR (ZIP) 文件本身呢?那是保证是相同的,还是只有它包含的类?因为规范似乎只涵盖类,所以散列整个文件可能不可靠。
  • 你是说Pack200解码出来的JAR?是的,它对于所有平台都是相同的——因为解压缩器的输出。但是,它可能与输入的 Jar 不同 - 所以再一次,Pack200 jar,解压缩,然后获取摘要并使用它。原因是 Pack200 实际上并没有压缩 Jar - 它是将它拆开,取出 .class 文件,重新压缩它们,然后在解压缩时构建一个新 Jar - Pack200 用于传输,Jar 用于 JVM 加载。所以构建的 jars 也受到上述限制 - 这包括文件订单等。
  • 粘贴的规范似乎只适用于单个类文件,而不适用于整个 JAR。
  • 很确定这是真的,即使规范没有明确说明 - 但你可能是对的!如果您担心 - 您可以使用带有 -repack 选项的 pack200 实用程序来使用 GZIP 压缩 JAR 文件,而不是将它们转换为完整的 Pack200 档案。如果你这样做,你可以只校验原始的罐子,用 --repack 选项调用 Pack200,然后当你在另一边解压它们时,校验和出来的罐子。见:download.oracle.com/javase/1.5.0/docs/tooldocs/share/…
  • 感谢您的努力。它有帮助,但我发现斯蒂芬不那么乐观的答案更准确。
【解决方案2】:

我正在寻找一些硬性规范来确认或否认这一点。

@Travis 的回答说重建的类文件与原始类文件不是逐字节相同的,这(显然)意味着 JAR 文件也不相同。

此外,没有任何文档说unpack200 将在所有平台上生成相同的 JAR 文件,我不希望它会这样。 (首先,不同的平台将运行不同版本的unpack200 ...)

如果无法确认或拒绝,那么这个后续问题如何。如何验证解压后的 jar 是否有效?想想半成品文件,伽马射线破坏文件中的单个位等等。

我也不认为有办法做到这一点。如果我们假设重新生成的 JAR 文件可能依赖于平台,那么我们就没有基准来生成校验和。

我认为您最好的选择是发送 pack200 文件的高质量校验和,并相信 unpack200 将正常工作或在失败时设置非零退出代码......就像任何正确编写的实用程序一样做。

顺便说一句,如果您担心随机错误,那么当 JVM 从 JAR 文件加载代码时,您将如何检测“宇宙射线”效应?明智的做法是使用 ECC 内存等,并将其留给硬件处理。

【讨论】:

  • 谢谢,我就是这么想的。看起来我可以验证签名 jar 的内容(stackoverflow.com/questions/1374170/…)。可能已经足够好了 - 使用校验和传输 .pack.gz,然后使用该方法解包并验证。宇宙射线有点夸张,但我对在磁盘上放置太久或提取一半的文件不是很有信心。
  • 是的......假设你不是指你已经打包的签名 JAR
猜你喜欢
  • 1970-01-01
  • 2013-12-13
  • 2015-02-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-08
  • 2019-03-23
  • 2011-09-25
相关资源
最近更新 更多