AWS LambdaのプロジェクトをGradleでビルド、テスト(JUnit4)する

EclipseのAWS Toolkitを利用するとLambdaのプロジェクト生成時にJUnitなどのテストも入っていて便利なのですが、Eclipseだけでビルドできる状態だとCIなどやりにくいのでGradleでビルドできるようにしてみたのでその時のメモを記載します。(Eclipse以外でもビルドできるのかもしれませんが...)

# とりあえず使いたい

プロジェクトは以下にあるのでご利用ください。

[LambdaGradle](https://github.com/toshihirock/LambdaGradle)


上記をcloneして環境変数JAVA_HOMEにJava8が指定された状態で

```
$cd LambdaGradle
$./gradlew build
```

とすることとでビルド、テスト、Lambda用のjarファイルが生成されるかと思います。`gradlew`を使っているのでGradle自体のインストールを事前に行っていなくてもビルドが可能です。Lambda用のjarファイルは**build/libs/LambdaGradle-0.0.1-SNAPSHOT.jar**に生成され、これをそのままLambdaにアップロードすれば利用できるかと思います。

# 以下より記載すること

+ AWS Tookkitで生成されるプロジェクトをGradleでビルドできるように変更をした時の内容
+ AmazonLinuxにGradleをインストールし、Lambdaをビルドする環境を構築。ここではGVMを使ってGradleをインストール面倒ならばgradlewを使ってもOKだと思います。(将来この環境でCIするイメージ)
+ MacOSXでEclipseを使って開発するための設定を行う

# AWS Toolkitで生成されるプロジェクトをGradleでビルドできるように変更した時のメモ

以下、実施したことを箇条書きします。

+ ソースコード、テストコードなどはAWS Toolkitで生成されるものを流用
+ build.gradleにビルド時のライブラリ依存関係を記載
+ ソースコード及びテストコードをMavenの規約に沿った場所に移動。ソースコードは**src/main/java**配下に、テストコードは**src/test/java**配下に配置。対象ファイル群のpackage名も合わせて変更
+ テストコードでjsonファイルの読み込みを行っており、jsonファイルを**src/test/resources**配下に移動
+ lambdaでは利用するライブラリも合わせてアーカイブする必要があるため、生成するjarファイルにライブラリも含めるよう設定。[gradleをつかって依存ライブラリを含む単一で実行可能なjarを生成する](http://qiita.com/mychaelstyle/items/9338f558903ac0c14bc3)を参考にさせていただきました。

最終的なbuild.graleは以下のようになりました。

```lang:build.gradle
apply plugin: 'java'

def defaultEncoding = 'UTF-8'
[compileJava, compileTestJava]*.options*.encoding = defaultEncoding

group = 'com.sample.lambda'
version = '0.0.1-SNAPSHOT'

description = "LambdaGradle"

sourceCompatibility = 1.8
targetCompatibility = 1.8

repositories {
    jcenter()
}

dependencies {
    compile 'com.amazonaws:aws-lambda-java-core:1.0.0'
    compile 'com.amazonaws:aws-lambda-java-events:1.0.0'

    testCompile 'junit:junit:4.11'
}

jar {
    from configurations.compile.collect { it.isDirectory() ? it : zipTree(it) }
}
```

その他ファイルやディレクトリの詳細はGithubを参照ください。

# [AmazonLinux]Java8のインストール

本項よりAmazonLinuxでの実施作業を記載します。LambdaはJava8を利用することができため、Java8をインスールします。

```
$sudo yum install java-1.8.0-openjdk.x86_64
$sudo yum install java-1.8.0-openjdk-devel.x86_64
```

デフォルトではJava7が利用されているため、Java8に変更します。
以下のコマンドを実行し、質問が聞かれたタイミングで`2`をタイプしてJava1.8を選択します。

```
$sudo /usr/sbin/alternatives --config java

2 プログラムがあり 'java' を提供します。

  選択       コマンド
-----------------------------------------------
*+ 1           /usr/lib/jvm/jre-1.7.0-openjdk.x86_64/bin/java
   2           /usr/lib/jvm/jre-1.8.0-openjdk.x86_64/bin/java

Enter を押して現在の選択 [+] を保持するか、選択番号を入力します:2
```

設定が反映されたか、またJAVA_HOMEの設定も正しいか確認します。

```
$java -version
openjdk version "1.8.0_45"
OpenJDK Runtime Environment (build 1.8.0_45-b13)
OpenJDK 64-Bit Server VM (build 25.45-b02, mixed mode)

$echo $JAVA_HOE
/usr/lib/jvm/jre

$ll /usr/lib/jvm/jre
lrwxrwxrwx 1 root root 21  7月  1 08:05 /usr/lib/jvm/jre -> /etc/alternatives/jre

$ ll /etc/alternatives/jre
lrwxrwxrwx 1 root root 37  7月  1 08:05 /etc/alternatives/jre -> /usr/lib/jvm/jre-1.8.0-openjdk.x86_64
```

# [AmazonLinux]GVMを使ってGradleをインストールする

最新のGradleが出たときなどに簡単に切り替えるためにGradleのインストールにはGVMを利用します。(Rubyのrbenvなどと同じようなもの)

[GVM](http://gvmtool.net/)

以下のワンライナーでインストールします。

```
$curl -s get.gvmtool.net | bash

Thanks for using

_____/\\\\\\\\\\\\__/\\\________/\\\__/\\\\____________/\\\\_
 ___/\\\//////////__\/\\\_______\/\\\_\/\\\\\\________/\\\\\\_
  __/\\\_____________\//\\\______/\\\__\/\\\//\\\____/\\\//\\\_
   _\/\\\____/\\\\\\\__\//\\\____/\\\___\/\\\\///\\\/\\\/_\/\\\_
    _\/\\\___\/////\\\___\//\\\__/\\\____\/\\\__\///\\\/___\/\\\_
     _\/\\\_______\/\\\____\//\\\/\\\_____\/\\\____\///_____\/\\\_
      _\/\\\_______\/\\\_____\//\\\\\______\/\\\_____________\/\\\_
       _\//\\\\\\\\\\\\/_______\//\\\_______\/\\\_____________\/\\\_
        __\////////////__________\///________\///______________\///__

                                       Will now attempt installing...

Looking for a previous installation of GVM...
Looking for unzip...
Looking for curl...
Looking for sed...
Installing gvm scripts...
Create distribution directories...
Create candidate directories...
Created for asciidoctorj: /home/ec2-user/.gvm/asciidoctorj
Created for crash: /home/ec2-user/.gvm/crash
Created for gaiden: /home/ec2-user/.gvm/gaiden
Created for glide: /home/ec2-user/.gvm/glide
Created for gradle: /home/ec2-user/.gvm/gradle
Created for grails: /home/ec2-user/.gvm/grails
Created for griffon: /home/ec2-user/.gvm/griffon
Created for groovy: /home/ec2-user/.gvm/groovy
Created for groovyserv: /home/ec2-user/.gvm/groovyserv
Created for jbake: /home/ec2-user/.gvm/jbake
Created for lazybones: /home/ec2-user/.gvm/lazybones
Created for springboot: /home/ec2-user/.gvm/springboot
Created for vertx: /home/ec2-user/.gvm/vertx
Prime the config file...
Download script archive...
Extract script archive...
Install scripts...
Attempt update of bash profiles...
Updated existing /home/ec2-user/.bash_profile
Updated existing /home/ec2-user/.bashrc
Attempt update of zsh profiles...
Created and initialised /home/ec2-user/.zshrc



All done!


Please open a new terminal, or run the following in the existing one:

    source "/home/ec2-user/.gvm/bin/gvm-init.sh"

Then issue the following command:

    gvm help

Enjoy!!!
```

ターミナルにログインし直すか、スクリプトを実行してくださいとあるので実行します。

```
source "/home/ec2-user/.gvm/bin/gvm-init.sh"
```

これでパスが通るので確認します。

```
$ gvm --help
==== BROADCAST =================================================================
* 25/06/15: Gradle 2.5-rc-1 has been released on GVM. #gradle
* 21/06/15: Legacy versions of #groovylang restored on GVM. Thanks @glaforge + @bintray!
* 17/06/15: GVM 2.4.2 is out. Fixes blank remote version & SSL cert issues on OSX.
================================================================================
Invalid command: --help

Usage: gvm <command> <candidate> [version]
       gvm offline <enable|disable>

   commands:
       install   or i    <candidate> [version]
       uninstall or rm   <candidate> <version>
       list      or ls   <candidate>
       use       or u    <candidate> [version]
       default   or d    <candidate> [version]
       current   or c    [candidate]
       outdated  or o    [candidate]
       version   or v
       broadcast or b
       help      or h
       offline           <enable|disable>
       selfupdate        [force]
       flush             <candidates|broadcast|archives|temp>

   candidate  :  asciidoctorj, crash, gaiden, glide, gradle, grails, griffon, groovy, groovyserv, jbake, lazybones, springboot, vertx
   version    :  where optional, defaults to latest stable if not provided

eg: gvm install groovy
```

以下のコマンドを利用して現在利用できるGradleのバージョンを確認します。

```
$gvm list gradle
================================================================================
Available Gradle Versions
================================================================================
     2.5-rc-1             1.12
     2.4                  1.11
     2.3                  1.10
     2.2.1                1.1
     2.2                  1.0
     2.1                  0.9.2
     2.0                  0.9.1
     1.9                  0.9
     1.8                  0.8
     1.7                  0.7
     1.6
     1.5
     1.4
     1.3
     1.2

================================================================================
+ - local version
* - installed
> - currently in use
===============================================================================
```

以下のコマンドでGradleの2.4をインストールします。また **Do you want gradle 2.4 to be set as default?** と聞かれるので`y`をタイプして利用するGradleのデフォルトを2.4としています。

```
$gvm install gradle 2.4

Downloading: gradle 2.4

  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
  0   354    0     0    0     0      0      0 --:--:--  0:00:01 --:--:--     0
100 62.4M  100 62.4M    0     0  24.9M      0  0:00:02  0:00:02 --:--:-- 55.6M

Installing: gradle 2.4
Done installing!

Do you want gradle 2.4 to be set as default? (Y/n): y

Setting gradle 2.4 as default.
```

gradleのバージョンを確認します。

```
$gradle -version

------------------------------------------------------------
Gradle 2.4
------------------------------------------------------------

Build time:   2015-05-05 08:09:24 UTC
Build number: none
Revision:     5c9c3bc20ca1c281ac7972643f1e2d190f2c943c

Groovy:       2.3.10
Ant:          Apache Ant(TM) version 1.9.4 compiled on April 29 2014
JVM:          1.8.0_45 (Oracle Corporation 25.45-b02)
OS:           Linux 3.14.35-28.38.amzn1.x86_64 amd64
```

Gradle2.4が使えていること、またJVMのバージョンがJava1.8となっていることが確認できました。

# [AmazonLinux]プロジェクトの取得とビルド、テストの実行

既に利用できるプロジェクトをGithubに置いているのでそれを取得します。まずは、Gitをインストールします。

```
$sudo yum install git
```

次にプロジェクトをcloneしてきます。

```
$git clone https://github.com/toshihirock/LambdaGradle.git
```

では早速、設定したGradle2.4を使ってビルドとテストを行ってみます。

```
$cd LambdaGradle
$gradle build
:compileJava
:processResources UP-TO-DATE
:classes
:jar
:assemble
:compileTestJava
:processTestResources
:testClasses
:test
:check
:build

BUILD SUCCESSFUL

Total time: 13.158 secs
```

上記結果を見れば分かるようにbuildコマンドによってビルド、jarファイル生成、テストを行っていることが分かります。

Lambda用のjarファイルは**build/libs/LambdaGradle-0.0.1-SNAPSHOT.jar**に配置されているかと思います。

上記をunzipするとjarファイル内に必要なクラスファイル群が含まれていることを確認できます。

# [MacOSX]gradlewを使ってビルドしてみる

本項よりローカルのMacOSXでの開発環境を設定します。
環境変数JAVA_HOMEを確認し、Java8が設定されているか確認。

```
echo $JAVA_HOME
/Library/Java/JavaVirtualMachines/jdk1.8.0_45.jdk/Contents/Home
```

AmazonLinuxと同じようにgit cloneしてきます。

```
$git clone https://github.com/toshihirock/LambdaGradle.git
```

MacOSXにはGradleを事前にインストールせず、gradlewを使ってビルドしてみます。gradlewコマンドを実行すると**gradle-wrapper.properties**に設定されたGradleをインストールしてビルドを実行してきてくれるのでチーム開発でGradleのバージョンを合わせる場合やそもそもGradleのインストールが面倒な時はとても便利です。

上記より初回実行時にはGradle本体と依存ライブラリを合わせてインストールしてくるので多少時間がかかりますが、ビルドが可能です。

```
$cd LambdaGradle
$./gradlew build
Downloading https://services.gradle.org/distributions/gradle-2.4-bin.zip
.............................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................
Unzipping /home/ec2-user/.gradle/wrapper/dists/gradle-2.4-bin/1lebsnfoptv8qpa10w6kyy5mp/gradle-2.4-bin.zip to /home/ec2-user/.gradle/wrapper/dists/gradle-2.4-bin/1lebsnfoptv8qpa10w6kyy5mp
Set executable permissions for: /home/ec2-user/.gradle/wrapper/dists/gradle-2.4-bin/1lebsnfoptv8qpa10w6kyy5mp/gradle-2.4/bin/gradle
:compileJava
:processResources UP-TO-DATE
:classes
:jar
:assemble
:compileTestJava
:processTestResources
:testClasses
:test
:check
:build

BUILD SUCCESSFUL

Total time: 31.702 secs
```

なお、テスト結果をHTMLでも確認できます

```
$open build/reports/tests/index.html
```

![Screen Shot 2015-07-02 at 8.38.22 AM.png](https://qiita-image-store.s3.amazonaws.com/0/20193/a81bfe7c-a21e-8ba3-aa88-1d6037d62306.png)

# [MacOSX]Eclipseにインポートして使ってみる

Javaの開発ではIDEを使いたいのでEclipseに本プロジェクトをインポートして使ってみます。

以下を参考にさせていただきました。

[Gradleで始めるJavaプロジェクトとEclipseのプラグイン](http://www.task-notes.com/entry/20150416/1429153200)

事前にEclipseをインストールしておきます。私の環境では**4.4.2**を利用しました。また、EclipseでもJava1.8を利用できる設定をしておきます。以前書いた以下の記事の下の方の記述を参考にしてください。

[AWS Toolkit for Eclipseを設定した時のメモ](http://qiita.com/toshihirock/items/d37ee8a41a11f2c4ffb2)

Eclipseを起動し、Gradleプラグインをインストールします。

+ help->EclipseMarketplace
+ 「gradle」で検索
+ install

![Screen Shot 2015-07-02 at 7.54.26 AM.png](https://qiita-image-store.s3.amazonaws.com/0/20193/10bd62c4-63f5-bc30-0d55-51ba016adf2c.png "Screen Shot 2015-07-02 at 7.54.26 AM.png")


インストール後、先ほどのプロジェクトをインポートします。

+ File->Import
+ Gradle->Gradle Project
+ 「Browse」で先ほどcloneしたプロジェクトを選択
+ 「BuildModel」を選択
+ Finish

これでEclipseでコード補完を使いつつ、開発ができます。

![Screen Shot 2015-07-02 at 8.01.19 AM.png](https://qiita-image-store.s3.amazonaws.com/0/20193/88afe0c1-fad3-adf5-005c-d4055b5a1268.png "Screen Shot 2015-07-02 at 8.01.19 AM.png")



Eclipse上でビルドする場合には以下を実行します。

+ 対象プロジェクトを選択
+ 右クリック->Run as->Build Gradle
+ Gradle Tasksでbuildを指定し、Run

![Screen Shot 2015-07-02 at 8.02.55 AM.png](https://qiita-image-store.s3.amazonaws.com/0/20193/f2b72e41-9c83-e796-edfa-d4630cf14937.png "Screen Shot 2015-07-02 at 8.02.55 AM.png")


これでOKです!