2017-02-01 18 views
3

AWSラムダ関数をJavaで記述します。 ラムダ(Terraform)をアップロードするために使用するツールは、新しいバージョンのラムダをアップロードする必要があるかどうかを追跡するために、jarファイルのSHA-256ハッシュを使用したいと考えています。javacを使用して、異なるプラットフォーム間でバイナリの同一クラスファイルを作成する方法は?

異なるOSプラットフォーム(WindowsおよびLinux)上の異なるJDKは、(同じ「更新」バージョンのJDKを使用する場合でも)若干異なるバイトコードを作成します。つまり、Windowsでラムダをアップロードしてから、Linux上でプロセスを再実行します。これにより、jarの別のハッシュコードが検出され、不要なラムダjarが再アップロードされます。

質問: 別のOSプラットフォームで同じバイトコードを作成するにはどうすればよいですか?

+4

やや違いますか? – EJP

+1

^これです。 2つの.classファイルの例を提供できますか? – Marco13

+0

放出されるバイナリコンテンツがわずかに異なります。私はそれらをwinmergeで比較すると、非テキストバイトのいくつかが異なっていました。私はスクリーンショットを投稿しようとします。 – Shorn

答えて

3

あなたはそれを強制することはできません。特定のソースコード式のバイトコードがどのように正確に見えるか、メンバーや属性の順番など、生成されるクラスファイルについては不明な点がいくつかあります。

各実行で同じファイルを正確に生成する必要はないため、コンパイラの実装では試してみません。まったく同じ入力(同じソースコードだけでなく、同じオプション)で同じソフトウェアを実行すると、同じ出力が生成されますが、同じコンパイラバージョンを必要とするのではなく、同じJREである。

残念ながら、は同じ実装と入力でも動作が異なる可能性があります。たとえば、一部のJava 7実装でjava.util.HashMapのハッシングをランダム化する試みがありました。javacが特定の成果物をHashMapに格納すると驚くことはありません。これはJava 8には当てはまりませんが、Java 9で導入される不変のマップにも当てはまります。コンパイラがその機能を使用するかどうかは予測できません。

正確に同じバイトコードを再現性よく生成する特定のjdkバージョンが見つかった場合は、今すぐ使えるかもしれませんが、次のバージョンにはそのプロパティがない可能性があることに注意してください。

同じバイトコードであっても、同じjarファイルを持つことは保証されていません。これは、jarファイル内のファイルの順序が不定であるためです。システム固有のファイルの反復順序に依存することがあります。さらに、jarファイルはタイムスタンプを格納するzipファイルなので、新たにコンパイルされたクラスファイルは、別の対策が必要な場合を除いて、別のファイルを生成します。すべてのエントリに対して特定のタイムスタンプを適用します。

2

この質問渡ってつまずくすべてのボディのために:

  • を見てまず最初に、各プラットフォーム上で

をJDKのベンダーをチェックすることは、私は/同じバージョンを持っていたが判明しています実際には異なるJDK(duh)を使用していました。

WindowsではOracle JDK、LinuxではOpenJDKを使用していました。これらをWindowsとLinuxの両方でAzul Zulu JDK(u112)に変更すると、これまでに書いた限られた量のJavaコードでは、まったく同じバイトコードが生成されているように見えます(ただし、Holgerの答えによれば、それは明らかに信頼されるべきではない)。

0

Eclipseのビルドプロセスでは、次のことを日常的にチェックします。最後のベースライン以降にgitに変更のないプロジェクトのコンパイル済みクラスファイルは、そのベースラインのjarファイルと比べてバイナリ差異があります。エクスペリエンスでは、コンパイラに関連する変更が行われた場合にのみ、実際の違いが発生することがわかります。

これは保証されませんが、通常は同じソースをコンパイルするときに同じコンパイラバージョンが同じバイトを生成するという経験的な証拠です。

この場合、コンパイラはecjです。

予期しないクラスファイルの変更を知らせるコンパレータからのrecent example logfileを参照してください。この変更は、特定のコンパイラ変更にトレースされました。対応するlogs of a releaseは空であると予想されます。

関連する問題