MacでAWS Lambda関数(java)を作るまで
思いつきで使った事のないMacBookAirを買い、思いつきでAWS Lambda関数を作ろうとしたものの、慣れないJavaScriptで書くのはストレスなので、慣れたJavaで作ろうとしたところ、すんなりといかなかったので残しておきます。
前提
- 2019.08.03現在のAWS Lambdaのランタイムは、ava-1.8.0-openjdk-Amazon linuxです
- homebrewというものがインストールされていること
- anyenvというものがインストールされていること
javaのインストール
java8の検索
Macにjavaをインストールします。lambdaランタイムがopenjdk8なのでhomebrewでopenjdkがインストールできるのか探します。
# おまじない
$ brew tap caskroom/versions
# openjdkを検索
$ brew search openjdk
==> Casks
adoptopenjdk adoptopenjdk8
openjdkのインストール
「adoptopenjdk8」という、いかにもjava8らしきものがあったのでこれをインストールします。途中でパスワードを聞かれますのでOSのパスワードを入力します。
# openjdk ver8をinstall
$ brew cask install adoptopenjdk8
Updating Homebrew...
==> Auto-updated Homebrew!
Updated 1 tap (homebrew/cask).
No changes to formulae.
==> Satisfying dependencies
==> Downloading https://github.com/AdoptOpenJDK/openjdk8-binaries/releases/downl
==> Downloading from https://github-production-release-asset-2e65be.s3.amazonaws
######################################################################## 100.0%
==> Verifying SHA-256 checksum for Cask 'adoptopenjdk8'.
==> Installing Cask adoptopenjdk8
==> Running installer for adoptopenjdk8; your password may be necessary.
==> Package installers may write to any location; options such as --appdir are i
Password: #osのパスワード入力
installer: Package name is AdoptOpenJDK
installer: Installing at base path /
installer: The install was successful.
🍺 adoptopenjdk8 was successfully installed!
javaバージョンの確認
macで有効になっているjavaバージョンを確認してみます。
$ java -version
openjdk version "1.8.0_222"
OpenJDK Runtime Environment (AdoptOpenJDK)(build 1.8.0_222-b10)
OpenJDK 64-Bit Server VM (AdoptOpenJDK)(build 25.222-b10, mixed mode)
jenvのインストール
jenvはjavaのバージョンをフォルダ毎に指定したりとかいい感じにやってくれるものです。
ReadMeに沿ってインストールします。
$ anyenv install jenv
jenvにJavaを追加する
jenv経由でjavaをインストールできないので、インストールされたjavaをjenvに教えてあげる必要があります。
$ jenv add $(/usr/libexec/java_home)
openjdk64-1.8.0.222 added
1.8.0.222 added
1.8 added
javaバージョンの確認
jenvが扱えるjavaバージョンの確認
$ jenv versions
* system (set by /Users/xxx/.anyenv/envs/jenv/version)
1.8
1.8.0.222
openjdk64-1.8.0.222
Mavenのインストール
ライブラリの定義やビルドをしやすくしたいのでMavenも入れます。
Mavenの検索
Mavenもhomebrewで入れられました。
$ brew search maven
==> Formulae
maven maven-completion maven-shell maven@3.2 maven@3.3 maven@3.5
==> Casks
mavensmate homebrew/cask-fonts/font-maven-pro
Mavenのインストール
特にバージョンにはこだわらないので最新をインストール。
$ brew install maven
Updating Homebrew...
==> Auto-updated Homebrew!
Updated 2 taps (homebrew/cask and caskroom/versions).
No changes to formulae.
==> Downloading https://www.apache.org/dyn/closer.cgi?path=maven/maven-3/3.6.1/binaries/apache-maven-3.6.1-bin.tar.gz
==> Downloading from https://www-eu.apache.org/dist/maven/maven-3/3.6.1/binaries/apache-maven-3.6.1-bin.tar.gz
######################################################################## 100.0%
🍺 /usr/local/Cellar/maven/3.6.1: 79 files, 10.2MB, built in 30 seconds
Visual Studio Codeの設定
Eclipseでも良いのですが、軽いと噂のVisual Studio Codeを使ってみたいのでインストール。
Visual Studio Codeのインストール
Download Visual Studio Codeからダウンロードしてインストールしてください。
VS CodeにJavaの拡張機能を追加
こちらに纏まっていますので、こちらを参照して「Java Extension Pack」の追加を行って下さい。
「java開発環境をvisual-studio-code-で整える」
※jenvのおかげかJAVA_HOMEの設定はせずとも大丈夫でした。
Javaの実装 & AWS Lambda関数にデプロイ
こちらに丁寧に纏まっていますので、こちらを参照して下さい。
「いまからはじめるJavaでAWS Lambda(ラムダ) 前編」
AWS API Gateway
パブリックに呼び出せるように、AWS LambdaのトリガーをAPI Gatewayにします。
が、ここで大ハマりしました。
上記までで、AWS Lambdaのテストはうまくいくのですが、API Gatewayを作ってテストを実行すると502でエラーとなるのです。
結論から言うと「API Gateway」の「統合リクエスト」の設定が初期値だとうまくいきませんでした。
AWS Lambdaにトリガーを設定
ここは素直に「+」ボタンでトリガーを追加して、下記のように選択します。
- API Gateway を選択
- API:素直に「新しいAPIを作成」
- セキュリティ:後からでも変更できるので、テストのしやすさを考えて「オープン」


統合リクエストの設定を変える
AWS Lambda コンソールにて、追加れたメソッドの「統合リクエスト」を選択します。

ここが大切です。
この中の「Lambdaプロキシ統合の使用」にチェックが入っているので、このチェックを外します。

このチェックを外す事で、うまくいくようになりました。
まとめ
API GatewayからLambdaのJava を呼び出すところで、リクエストBODYのjsonの内容をJavaの入力パラメータのPOJOに値を詰める処理が動くわけですが、「Lambdaプロキシ統合の使用」にチェックが入っているとどうもここがうまくいきません。
推測するに、API Gatewayでは、リクエストの情報と一緒にAWSのメタな情報もセットで持ち回っており、「Lambdaプロキシ統合の使用」にチェックが入っていると、メタな情報もLambdaに渡せる反面、Lambda側でもそのつもりで受け取る実装にしておかないとダメで、今回の実装はjsonの内容しか受け取るようにしていなかったので失敗していたようです。
「Lambdaプロキシ統合の使用」のチェックを外すとリクエストBODYのみLambdaに渡すようになり、POJOで受け取れるようになりました。