AWS Lambda(Java)をVSCodeのGradleプロジェクトで開発する方法
Lambdaの言語は色々ありますが、Java8,11,17がサポートされています。
最近Javaもコールドスタート対策されて約10倍くらい早くなったらしいので、今後Lambdaの言語の選択肢としてJavaも出てくるかもしれません。
今回試しにJava8で簡単なLambdaを作成し、時間を計測しようとしたのですがいくつか注意点があったのでメモです。
GradleをC:\gradleにインストールしている前提です。
項目 | バージョン |
---|---|
Gradle | 6.0.1 |
jarまたはzip形式でアップロードする必要がある
GradleプロジェクトをビルドしてJar形式にしてアップロードする必要があります。
zipでも良いようですがこちらは、Gradleタスクの設定が必要?と思われます。※マニュアルにはそう書いています
マネージメントコンソールでソースが見れない
node.jsばかりしていたので気づかなかったですが、JavaやC#の場合はマネジメントコンソールでソースを見ることができません。
これはやはりコンパイルが必要だからでしょう。node.jsのようなスクリプトは修正してすぐ動作が確認できるのでマネジメントコンソールでも修正が可能ですが、やはりJavaなどはそうはいかないですね。
VSCodeでJavaを開発する
「VSCodeでJava開発をする方法 」を参考にしてください。今回はGradleプロジェクトを作成したいので以下コマンドでインタラクティブに作成していきます。
※プロジェクト名とフォルダ名は同じにします
$ gradle init --type java-application Starting a Gradle Daemon (subsequent builds will be faster) Select build script DSL: 1: groovy 2: kotlin Enter selection (default: groovy) [1..2] 1 Select test framework: 1: junit 2: testng 3: spock Enter selection (default: junit) [1..3] 1 Project name (default: gradleproject): sample Source package (default: sample): confrage BUILD SUCCESSFUL in 47s 2 actionable tasks: 2 executed
これで以下のようなファイル構成がsampleフォルダ配下に作成されます。
sampleフォルダをVSCodeで開いてGradleプロジェクトに適したプラグインを入れます。
VSCodeのプラグイン
「Extension Pack for Java」を入れます。※マストです
「Gradle for Java」を入れるとサイドパネルでビルドタスクがGUIで実行できます。
Gradle for Javaを入れておくと便利です。プロジェクト直下に以下のいずれかがないと表示されませんので注意して下さい。
- gradlew
- gradlew.bat
- build.gradle
- settings.gradle
スケルトンコードが作成されたので実行する
ここまでいけたら実行してみます。
コマンド | 内容 |
---|---|
gradle run | 実行する |
gradle build | ビルドする |
gradle clean | クリーンする |
コマンドプロンプトからgradle run
します。
$ gradle run Starting a Gradle Daemon, 2 incompatible Daemons could not be reused, use --status for details > Task :run Hello world. BUILD SUCCESSFUL in 15s 2 actionable tasks: 2 executed
これでVSCodeでGradleプロジェクトを実行することができました。
今回はこのGradleプロジェクトをjar or zip化してLambdaで実行したいので、build.gradleに必要なライブラリを2つ追加します。
compile fileTree(dir: 'jars', include: '*.jar') compile ( 'com.amazonaws:aws-lambda-java-core:1.2.0', 'com.amazonaws:aws-lambda-java-events:2.2.7' )
次にタスクを追加します。
task buildZip(type: Zip) { from compileJava from processResources into('lib') { from configurations.runtimeClasspath } } build.dependsOn buildZip
これでbuild.gradleを保存し、コマンドプロンプトからgradle build
を実行します。
$ gradle build BUILD SUCCESSFUL in 8s 8 actionable tasks: 7 executed, 1 up-to-date
依存関係のあるライブラリがダウンロード出来たら、以下のように表示されると思います。
成功したらGradleプロジェクト直下のbuild\distributions配下にzipファイルが作成されます。
このzipファイルをLambdaにアップロードするのですが、このままだとエラーになります。
build.gradle
plugins { id 'java' id 'application' } repositories { jcenter() mavenCentral() } dependencies { compile fileTree(dir: 'jars', include: '*.jar') compile( 'com.amazonaws:aws-lambda-java-core:1.2.0', 'com.amazonaws:aws-lambda-java-events:2.2.7' ) testImplementation 'junit:junit:4.12' } mainClassName = 'confrage.App' task buildZip(type: Zip) { from compileJava from processResources into('lib') { from configurations.runtimeClasspath } } build.dependsOn buildZip
App.javaの中身を編集する
実行されるクラスはいくつかお作法があります。
- com.amazonaws.services.lambda.runtime.RequestHandlerをインプリメントする
- handleRequestメソッドをオーバーライドする
- インデックスハンドラ名は、package名.クラス名::handleRequestとする
今回の場合、インデックスハンドラ名は「confrage.App::handleRequest」となります。
簡単に以下のように作成しました。インプットは文字列で、それを数値にして返すだけです。
App.java
package confrage; import com.amazonaws.services.lambda.runtime.Context; import com.amazonaws.services.lambda.runtime.RequestHandler; public class App implements RequestHandler<String, Integer> { @Override public Integer handleRequest(String input, Context context) { return Integer.valueOf(input); } }
再度、ビルドしてzipファイルをアップロードします。インデックスハンドラ名変更も忘れずに行います。これで保存し、「テスト」を押します。
何らかのエラーが出た場合は、インプットの引数が間違えている可能性が高いです。今回であれば数値を文字列型にしておかないとエラーとなります。
再度、「テスト」をしてOKでした。
感想
簡単なhello world.を出力するプログラムを作成しようと思っただけなのに意外にもJavaは難しいという感じでした。
また、デフォルトでタイムアウト:15秒、メモリ:512MBとなっていたので、やはりnode.jsやGo言語と比較するとまだまだ遅いのかもしれません。
KHI入社して退社。今はCONFRAGEで正社員です。関西で140-170/80~120万から受け付けております^^
得意技はJS(ES6),Java,AWSの大体のリソースです
コメントはやさしくお願いいたします^^
座右の銘は、「狭き門より入れ」「願わくは、我に七難八苦を与えたまえ」です^^
コメント