Play 2.5に入門　②環境構築とPlay Javaつまみ食い

Play 2.5に入門、今回はインストールと初回起動を行う。Playの初回起動はかなり遅いので、作業待ち時間に、初使用となるPlay Java界隈の情報を調べることとする。

#環境構築

##インストール
Play 2.2以降のインストールには必要なものは以下の２つ

- Java 8
- Scala製のビルドツールsbtの改訂版(?)であるTypesafe Activator

Scalaのsbt使いの人の中には、sbtでPlay環境を使っている方もいるようだが、入門時は素直に[公式サイトからActuvator入りのPlayをダウンロード](https://www.playframework.com/download)した方が良い:

![スクリーンショット 2016-04-24 14.55.25.png](https://qiita-image-store.s3.amazonaws.com/0/16455/11bb9f93-5b1c-0b78-426a-8e5a5fadb8ae.png)

ダウンロード画面のバージョン2.5.2の横に"Steamy"なる単語が並んでいるが、これはPlayframeworkバージョン2.5につけられたニックネームらしい(Playframework2.4のニックネームは、"Damiya")。...Androidのお菓子シリーズに影響を受けたのだろうか。

Windowsな人のインストールについては、[Typesafe ActivatorでPlay framework 2実行環境を整える](http://qiita.com/nownabe/items/996df00392e60b5ea3e0)に従えば良いはず。

### (今回)Macでhomebrew経由でTypesafe Activatorをインストール
Macでhomgbrewを使う場合は、以下のようにコマンドのみで良い(activatorの)。

```shell-session
brew install typesafe-activator
activator -help
```
*※activator -helpすることで、activatorの動作に必要なjarがダウンロードされる。*

※今回の導入時点での環境は、以下。

- Mac OS(10.11.4)
- Java 8 update 91
- Homebrew 0.9.9 (git revision 1451; last commit 2016-04-23)

※旧バージョンのhomebrewが壊れていた際には、こちらの[対処方法](http://j.mp/reinstbrew)で(..お世話になった)。

## アプリの雛形生成
[Play2.3日本語版のインストール解説](https://www.playframework.com/documentation/ja/2.3.x/Installing)通りに行える。

すなわち、"activator new your-first-app play-java"コマンドで、Play Javaアプリの雛形が出来上がる。

```
cd /your/play/folder
activator new your-first-app play-java
```

この時点でのフォルダ構成は以下のとおり:

```
$ tree
.
├── LICENSE
├── README
├── app
│   ├── Filters.java
│   ├── Module.java
│   ├── controllers
│   │   ├── AsyncController.java
│   │   ├── CountController.java
│   │   └── HomeController.java
│   ├── filters
│   │   └── ExampleFilter.java
│   ├── services
│   │   ├── ApplicationTimer.java
│   │   ├── AtomicCounter.java
│   │   └── Counter.java
│   └── views
│       ├── index.scala.html
│       └── main.scala.html
├── bin
│   └── activator
├── build.sbt
├── conf
│   ├── application.conf
│   ├── logback.xml
│   └── routes
├── libexec
│   └── activator-launch-1.3.9.jar
├── project
│   ├── build.properties
│   └── plugins.sbt
├── public
│   ├── images
│   │   └── favicon.png
│   ├── javascripts
│   │   └── hello.js
│   └── stylesheets
│       └── main.css
└── test
    ├── ApplicationTest.java
    └── IntegrationTest.java

```

プロジェクトフォルダに移動しての二回目のactivatorコマンド実行により、Play Javaアプリの立ち上げに必要な依存性解決がなされる(ここで結構な"待ち"が入る)。

```
cd your-first-app
activator
```

#Play Javaつまみ食い
*待ち時間を利用して、Play Javaで気になることを調べておく。*

## ①GAE(Google App Engine)対応は下火
Play 1.xの頃は、Google App EngineでPlayを動かす、的な話が多かった気がする(未体験)。公式サイトでも1.0の頃のGAE対応についてのドキュメントが[残っている](https://www.playframework.com/documentation/1.0/gae)。

が、そんな記事は2012年くらいまでな気がした。JavaでGAEという取り組み自体が下火なのだろうか...

## ②ORMのebeanとLombokは組み合わせ可
Play JavaとPlay Scalaと比較した際に、RDBアクセスについては、Javaのebean ORMに好感を持った。なんというか普通に便利な感じがよさ気*(ScalaのRDBアクセス事情については必要に応じ調べる)*。

で、少し気になったのが、ebeanと脱ボイラープレートなLombokとの関係。
以下によると、どうやら共存可能な模様なようで一安心(ユニットテストが楽になるとのこと):
[EBeanでもユニットテストの導入はスマートです。そう、Lombokならね。](http://cs.hatenablog.jp/entry/2013/12/06/000020)

```java
@Entity @Table(name="items") // ebean ORM
@Data                        // Lombok
public class Item extends Model implements IItem {
    @Id @NotNull
    public Integer id;
    @NotNull
    public String name;
}
```

上ブログで書かれているユニットテストの導入時の話は、[Play Framework でエンティティを使う際の注意点](http://qiita.com/fukushiw/items/64993db74e1454554b7c)で書かれている、PlayFrameworkエンハンスによる、"app"配下にあるソースコードのエンティティに対してのgetter/setter自動挿入の話と関わるものと思っている。このことが、app配下外のソースコード並びに、scalaコードからのEbeanの@Entityが付されたモデルの呼び出し時に、フィールドが存在しない場合のNullPointerException発生につながるとのこと。注意点の記事では、それゆえ、"エンティティへの直アクセスを禁止しsetter/getterは明示的に宣言せよ"と書いているが、実際には、Lombokの@Dataアノテーションで対策済となるのでは思っている。

あるいは、

```java
@Entity @Table(name="items") // ebean ORM
@Data                        // Lombok
public class Item extends Model implements IItem {
    @Id @NotNull
    private Integer id;
    @NotNull
    private String name;
}
```
とフィールドをprivateとしておけば良いのか。このあたり、scalaコードのJavaコードの混在にとって大事なところなので、後で検証したい。

## ③Play2.4以降のDependency Injection （DI）には、Google Guiceが選択可
Play2.4以降の特徴の１つである、DIの全面採用。

[Play Framework 2.4 + コンパイル時DIで Play Module を利用する方法](http://qiita.com/shogogg/items/f5c0c823b6f5b31974ec)に延べられているとおり、Playで利用できるDIには二種類ある。

- [Runtime Dependency Injection](https://www.playframework.com/documentation/ja/2.4.x/ScalaDependencyInjection)（実行時の動的なDI）
- [Compile Time Dependency Injection](https://www.playframework.com/documentation/ja/2.4.x/ScalaCompileTimeDependencyInjection)（コンパイル時の静的なDI）

*※上のリンクはPlay2.4系のドキュメント。...Play2.5系のドキュメントはまだ未整備...*

このうち、Runtime DIでGoogle Guiceが利用されている。Java使いにとっては、古くからあるGuiceは親しみやすいところだろう。逆にScala使いは、Guiceを(Javaっぽくて)微妙と思う人が多いらしく、上記事の人のようにCompile Time DIを採用したり、試行錯誤している模様。

使ってみないと分からないが、Java使いの方がPlayのDIには馴染みやすいのかもしれない。


# Play Java実行
...と調べものをしているうちに、activatorがjarをかき集め終わったので、Play Javaを実行する
ローカルホスト(9000番ポート)での実行は以下のとおり。
> activator run

しばし待つとコンパイルとデプロイが終わり、localhost:9000にアクセスできる:

![スクリーンショット 2016-04-24 19.40.58.png](https://qiita-image-store.s3.amazonaws.com/0/16455/7883de28-2d3b-24c4-4bc6-fa0e65f16c66.png)

Play Javakの簡単な解説とAPIブラウザへのリンクが表示されている。
 

## 自動生成されるコードのDI周りを眺める。

まずはcomv/routesを眺める。

```
# An example controller showing a sample home page
GET     /                           controllers.HomeController.index
# An example controller showing how to use dependency injection
GET     /count                      controllers.CountController.count
# An example controller showing how to write asynchronous code
GET     /message                    controllers.AsyncController.message

# Map static resources from the /public folder to the /assets URL path
GET     /assets/*file               controllers.Assets.versioned(path="/public", file: Asset)
```
ホーム以外に、以下のアプリもあるとのこと。

- http://localhost:9000/count => アクセスカウンターのデモ
- http://localhost:9000/message => ただの挨拶(hello world相当)

CountController.javaを見ておこう:

```java

package controllers;

import javax.inject.*;
import play.*;
import play.mvc.*;

import services.Counter;

/**
 * This controller demonstrates how to use dependency injection to
 * bind a component into a controller class. The class contains an
 * action that shows an incrementing count to users. The {@link Counter}
 * object is injected by the Guice dependency injection system.
 */
@Singleton
public class CountController extends Controller {

    private final Counter counter;

    @Inject
    public CountController(Counter counter) {
       this.counter = counter;
    }

    /**
     * An action that responds with the {@link Counter}'s current
     * count. The result is plain text. This action is mapped to
     * <code>GET</code> requests with a path of <code>/count</code>
     * requests by an entry in the <code>routes</code> config file.
     */
    public Result count() {
        return ok(Integer.toString(counter.nextCount()));
    }

}
```

@InjectのところでDIが使われている。このコントローラーは、counterがいかなるカウンターであるかは知らず、また、counter.nextCount()がどのように実行されるかも型情報以外は知らないというわけだ。

実際にInject(注入)されているAtomicCounter.java:

```java

package services;

import java.util.concurrent.atomic.AtomicInteger;
import javax.inject.*;

/**
 * This class is a concrete implementation of the {@link Counter} trait.
 * It is configured for Guice dependency injection in the {@link Module}
 * class.
 *
 * This class has a {@link Singleton} annotation because we need to make
 * sure we only use one counter per application. Without this
 * annotation we would get a new instance every time a {@link Counter} is
 * injected.
 */
@Singleton
public class AtomicCounter implements Counter {

    private final AtomicInteger atomicCounter = new AtomicInteger();

    @Override
    public int nextCount() {
       return atomicCounter.getAndIncrement();
    }

}
```

その他、Counterインターフェースを持つ、任意のCounterが作れる。このあたり、後でためすべきだろう。

#環境構築時点の感想
環境構築については、以前の(2.0/2.1頃)のPlayとあまり変わりない印象。とりあえず実行するところまでは、はまりどころが少ない。初回の実行までにはこれまた従来同様、時間がかかる。その間、いろいろググッて、Play2.2以降の皆さんのはまりっぷりを各所で眺めることとなった。Play2.5にはどんなはまり道が待っているのだろうか^^;