少しずつですがJavaのビルドツール周りも分かりかけてきたなという矢先、エラーで数時間ハマりました…😭
開発環境
- OS: Windows11 Home 21H2
$ node -v v16.14.2 $ npm -v 8.5.0 $ sls --version Framework Core: 2.34.0 Plugin: 4.5.3 SDK: 4.2.2 Components: 3.8.2 $ java --version openjdk 17.0.2 2022-01-18 OpenJDK Runtime Environment (build 17.0.2+8-86) OpenJDK 64-Bit Server VM (build 17.0.2+8-86, mixed mode, sharing) $ aws --version aws-cli/2.1.19 Python/3.7.9 Windows/10 exe/AMD64 prompt/off
経緯
- Serverless Frameworkのテンプレート
aws-java-maven
を使って、プロジェクトを新規作成。(sls create -t aws-java-maven
) pom.xml
に記載のライブラリに脆弱性のあるものが含まれているとIDEに怒られていた為、バージョンを修正。(かの有名なlog4jの脆弱性修正前のバージョンがテンプレートとして使われていました。これ普通に危ない…。)mvn install
,mvn package
でビルド。sls deploy
でAWS Lambdaへデプロイを実行。結果は成功。- ローカルから
sls invoke
を実行し、Lambdaのテストをしてみたが下記のエラーが発生。
$ sls invoke -f hello { "errorMessage": "com/fasterxml/jackson/core/util/JacksonFeature", "errorType": "java.lang.NoClassDefFoundError", "stackTrace": [ "com.fasterxml.jackson.databind.ObjectMapper.<init>(ObjectMapper.java:673)", "com.fasterxml.jackson.databind.ObjectMapper.<init>(ObjectMapper.java:576)", "com.serverless.ApiGatewayResponse$Builder.<clinit>(ApiGatewayResponse.java:53)", "com.serverless.ApiGatewayResponse.builder(ApiGatewayResponse.java:46)", "com.serverless.Handler.handleRequest(Handler.java:20)", "com.serverless.Handler.handleRequest(Handler.java:12)" ], "cause": { "errorMessage": "com.fasterxml.jackson.core.util.JacksonFeature", "errorType": "java.lang.ClassNotFoundException", "stackTrace": [ "java.net.URLClassLoader.findClass(URLClassLoader.java:387)", "java.lang.ClassLoader.loadClass(ClassLoader.java:418)", "java.lang.ClassLoader.loadClass(ClassLoader.java:351)", "com.fasterxml.jackson.databind.ObjectMapper.<init>(ObjectMapper.java:673)", "com.fasterxml.jackson.databind.ObjectMapper.<init>(ObjectMapper.java:576)", "com.serverless.ApiGatewayResponse$Builder.<clinit>(ApiGatewayResponse.java:53)", "com.serverless.ApiGatewayResponse.builder(ApiGatewayResponse.java:46)", "com.serverless.Handler.handleRequest(Handler.java:20)", "com.serverless.Handler.handleRequest(Handler.java:12)" ] } } ...
エラー発生時点のpom.xml
上述のエラー発生前にlog4j-core
, jackson-databind
に脆弱性があるとIDEから指摘されていた為、推奨のバージョンに修正をしていましたが、どうもこれではうまく動作しませんでした。
... <dependencies> <dependency> <groupId>com.amazonaws</groupId> <artifactId>aws-lambda-java-log4j2</artifactId> <version>1.5.1</version> </dependency> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-core</artifactId> <!-- ↓バージョン変更箇所 --> <version>2.17.2</version> </dependency> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-api</artifactId> <version>2.8.2</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-core</artifactId> <version>2.9.10</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <!-- ↓バージョン変更箇所 --> <version>2.13.2</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-annotations</artifactId> <version>2.9.10</version> </dependency> </dependencies> ...
原因
pom.xml
の依存関係にあるライブラリ同士のバージョンに差異があり、実行時にエラーが発生していた。
具体的には以下のように修正をすることで、正常にLambdaが動作しました。
対応
pom.xmlの修正
groupIdが同じライブラリ同士は、バージョンを揃えてあげる必要があったようで、今回はorg.apache.logging.log4j
, com.fasterxml.jackson.core
を修正しました。
... <dependencies> <dependency> <groupId>com.amazonaws</groupId> <artifactId>aws-lambda-java-log4j2</artifactId> <version>1.5.1</version> </dependency> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-core</artifactId> <version>2.17.2</version> </dependency> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-api</artifactId> <version>2.17.2</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-core</artifactId> <version>2.13.2</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.13.2</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-annotations</artifactId> <version>2.13.2</version> </dependency> </dependencies> ...
再度デプロイ
pom.xml
を修正したらもう1度ビルド+デプロイを実行。
$ mvn install $ mvn package $ sls deploy
動作のテスト
$ sls invoke -f hello { "statusCode": 200, "body": "{\"message\":\"Go Serverless v1.x! Your function executed successfully!\",\"input\":{}}", "headers": { "X-Powered-By": "AWS Lambda & serverless" }, "isBase64Encoded": false }
JSONのレスポンスが返ってきました!どうやらLambdaが正しく動作してくれたようです😊
Node.jsでも依存関係で辛いことがたまにありますが、Javaでも注意が必要ですね。