Windows環境でAWS Lambdaのカスタムランタイム上で動作させる用にネイティブコンパイルする際に躓いた点と解決方法を記録に残しておきます。
つまずいた点と解決方法
WindowsでLinux用にネイティブコンパイルするときは、DockerかWSLを使うのが手っ取り早いと思います。私はDockerを使いました。
AllowVMInspectionオプションを無効にする
AllowVMInspectionオプションが有効なままネイティブコンパイルすると、Lambda実行時に以下のエラーが発生しました。
2021-02-05T11:31:14.620+09:00 Fatal error: Util_sun_misc_Signal.ensureInitialized: CSunMiscSignal.open() failed.
2021-02-05T11:31:14.641+09:00 END RequestId: 47d11207-942c-4910-93a8-5ff77afe77f3
2021-02-05T11:31:14.641+09:00 REPORT RequestId: 47d11207-942c-4910-93a8-5ff77afe77f3 Duration: 119.84 ms Billed Duration: 120 ms Memory Size: 128 MB Max Memory Used: 6 MB
2021-02-05T11:31:14.641+09:00 RequestId: 47d11207-942c-4910-93a8-5ff77afe77f3 Error: Runtime exited with error: exit status 99 Runtime.ExitError
ネイティブコンパイルするコマンド「native-image」を実行するときに、AllowVMInspectionをOFFにしてあげる必要がありました。
改行コードはLF
改行コードがCRLFのまま、ネイティブコンパイルしてLambda(Linux環境)で実行すると、エラーになりました。
LFに変換するのをすっかり忘れてました。
以下のエラーは、Micronautのスタックトレースですが、フレームワークを使わない場合においても同様のエラーが発生すると思われます。
2021-02-05T13:52:46.161+09:00 io.micronaut.http.codec.CodecException: Error decoding JSON stream for type [book]: Unrecognized token 'aaa': was expecting (JSON String, Number, Array, Object or token 'null', 'true' or 'false')
io.micronaut.http.codec.CodecException: Error decoding JSON stream for type [book]: Unrecognized token 'aaa': was expecting (JSON String, Number, Array, Object or token 'null', 'true' or 'false')
2021-02-05T13:52:46.161+09:00 at [Source: (String)"aaa"; line: 1, column: 4]
ネイティブコンパイルする前に一括でLFに変換してあげるのが良いと思います。
find . \( -name 'src/*' -o -name '\*.sh' \) -type f | nkf -Lu --overwrite
ネイティブコンパイルとOut Of Memory
ネイティブコンパイルするには、結構メモリを必要とします。
そもそもマシンのメモリが足りない場合等も考えられますが、僕の環境では、Dockerで確保できるメモリ以上にメモリを使おうとして、ネイティブコンパイル時にエラーになってました。
native-image実行時のメモリ上限を8Gに制限してあげると、ネイティブコンパイルできました。少なすぎるとネイティブコンパイルに失敗します。
関連記事
GraalVM native imageでAWS Lambda用にネイティブコンパイルして、Javaと速度比較した話