如何知道基于 AMD64 构建的 .jar 是否可以 运行 在 ARM 上完美运行?

How to know if a .jar built on AMD64 will run flawlessly on ARM?

我在 ARM 架构的 docker 中构建了一个 .jar,在 AMD64 上构建了一个 .jar

两个.jar文件的大小相同,但是vbindiff说它们的内容完全不同。

我在我的 AMD64 计算机上测试了两个 .jar 文件,并且相反的口号“随处构建,运行 一次”成立。

我的假设是,这与 Java 本机接口 (JNI) 有关。 .jar 是一个 Spring Boot Webflux 后端。不幸的是,我不知道它或任何其他依赖项是否使用 JNI。

我注意到 ARM 映像安装了 JDK 17.0.3,而 AMD64 映像安装了 JDK 17.0.2 . 但这应该不是问题,因为我使用 Gradle 包装器 构建了两个 .jar,它指定了确切的工具链下载并用于构建项目:

kotlin("jvm") version "1.6.10"

造成差异的原因可能是什么?我可以假设 .jar 可以在任何具有兼容 JVM 的平台上使用吗?

编辑:我听从了 Thomas 的建议并使用 diff -r 比较了 .jar 文件的提取内容。它们是相同的。

但是,diff 确认 .jar 文件本身是不同的。

刚刚了解到.jar格式是基于.zip的格式,可以使用多种压缩方式,也可以在文件头中包含额外的信息,比如'last modified'或者可选的 OS 特定属性。谜底揭晓。

我真的说不出为什么会有差异,但我几乎可以肯定 .jar 文件将 运行 放在任何地方,只要您的 java 中没有任何平台特定的内容代码。您的代码是为 JVM 编译的,而不是为 CPU 的体系结构编译的。 JVM 负责将 java 二进制文件“翻译”为机器代码,因此它可以 运行 任何地方。

您可以使用 jar tf myfile.jar 列出 .jar 中的文件。如果唯一的内容是 .class 文件和 META-INF/ 中的清单数据,那么它很可能是 100% 可移植的。如果您看到 .so.dll.dylib 等其他文件,那么其中的本机代码可能会带来麻烦。

以下是列出所有可能值得仔细查看的文件的方法:

jar tf myfile.jar | grep -Pv '^META-INF/|(\.class|/)$'

由于您已经在两个不同的平台上构建了 .jar,您还可以使用 jar xf myfile.jar 提取它们的内容并使用 diff -r 递归比较它们。这是一种比直接比较档案更可靠的检测差异的方法,尽管我认为 .class 文件可能不 byte-wise 相同,即使它们在语义上相同。