如何使用javac在不同平台上创建二进制相同的类文件? [英] How to use javac to create binary identical class files across different platforms?

查看:139
本文介绍了如何使用javac在不同平台上创建二进制相同的类文件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我用Java编写AWS Lambda函数。
我用来上传lambda的工具( Terraform )想要使用我的jar文件的SHA-256哈希来跟踪是否需要上传一个新版本的lambda。

I write my AWS Lambda functions in Java. The tool I use to upload my lambdas (Terraform) wants to use the SHA-256 hash of my jar file to track if a new version of a lambda needs to by uploaded.

问题是,不同操作系统平台(Windows和Linux)上的不同JDK创建略有不同的字节码(即使使用相同的更新版本的JDK)。这意味着,如果我在Windows上上传lambda,然后在Linux上重新运行该进程 - 它将检测jar的不同哈希码并不必要地重新上传lambda jar。

The problem is, different JDKs on different OS platforms (Windows and Linux) create slightly different bytecode (even when using the same "update" version of the JDK). This means, if I upload a lambda on Windows, then re-run the process on Linux - it will detect a different hash code for the jar and re-upload the lambda jar unnecessarily.

问题
如何强制javac在不同的OS平台上创建相同的字节码?

The question: How do I force javac to create identical bytecode on different OS platforms?

推荐答案

你不能强制执行。有关生成的类文件的几个未指定的详细信息,例如某些源代码表达式的字节代码必须如何精确查看或成员或属性的顺序。

You can’t enforce that. There are several unspecified details about the generated class files, like how the byte code of certain source code expressions has to look exactly or the order of members or attributes.

从那里没有要求在每次运行中生成完全相同的文件,编译器实现甚至都没有尝试。可以假设,当您使用完全相同的输入执行相同的软件(不仅是相同的源代码,而且是相同的选项)时,它将产生相同的输出,但这不仅需要相同的编译器版本,而且也是相同的JRE。

Since there is no requirement to produce exactly the same file in each run, the compiler implementation does not even try. It’s fair to assume that when you execute the same software with exactly the same input (not only the same source code, but also the same options), it will produce the same output, but that does not only require the same compiler version, but also the same JRE.

不幸的是,即使使用相同的实现和输入,可能也会有不同的行为。例如,有些尝试在一些Java 7实现中随机化 java.util.HashMap 的散列,如果 javac 将某些工件存储在 HashMap 中。这不适用于Java 8,但可能适用于在Java 9中引入的不可变映射。编译器是否将使用该功能是不可预测的。

Unfortunately, there might be different behavior even with the same implementation and input. E.g., there were attempts to randomize the hashing of java.util.HashMap in some Java 7 implementations and it wouldn’t be surprising if javac stores certain artifacts in a HashMap. This does not apply to Java 8, but might apply to the immutable maps to be introduced in Java 9. Whether the compiler will use that feature is not predictable.

所以如果你找到了一个可重复生成完全相同字节代码的特定jdk版本,你可能现在可以使用它,但必须注意下一个版本可能没有该属性。

So if you found a particular jdk version that reproducibly generates exactly the same byte code, you might be fine with it now, but have to be aware that the next version might not have that property.

到目前为止还没有解决过,即使拥有相同的字节码也不能保证具有相同的 jar 文件,因为jar文件中的文件顺序是不确定的。它可能取决于系统特定的文件迭代顺序。此外,由于jar文件是存储时间戳的zip文件,因此新编译的类文件确实会产生不同的文件,除非您采取其他措施,例如:为所有条目强制执行特定时间戳。

It has not been addressed so far that even having the same bytecode does not guaranty to have the same jar file, as the order of the files within the jar files is unspecified. It might depend on the system specific file iteration order. Further, since jar files are zip files which store timestamps, newly compiled class file do definitely yield a different file, unless you are taking additional measures, e.g. enforce a particular timestamp for all entries.

这篇关于如何使用javac在不同平台上创建二进制相同的类文件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆