GAE JavaでJava8+Spring Bootをやってみました。
基本は公式サイトをやってれば良いんですがちょいちょい開発環境という点でハマったりしたのでメモ。
というか公式のドキュメントがけっこうバラバラにあってどれを参照するのがいいのかよくわからなかったりして大変でした。
今回はこのUsing Apache Maven and the App Engine PluginをベースにGitHubのリポジトリから内容を拝借しながら作ってみました。
間違ったりこうした方がいいとかあれば遠慮なく編集リクエストよろしくお願いします。
本当はGradle派ですが、Gradleで色々試したけど紆余曲折あって辛くてやめました。
たぶんもうちょいちゃんとやれば大丈夫なはずです。
今回のコードはGithubに置きました。
必要なもの
- Java8
- Maven 3.5
- Gcloud SDK
- AppEngine SDK Java
- IntelliJ IDEA
- Google Cloud Toolsプラグイン
アプリケーション作成
Maven Archetypeで作成します。
たぶんこれが一番きれいに作れると思います。
mvn archetype:generate -Dappengine-version=1.9.54 \
-Djava8=true \
-DCloudSDK_Tooling=true \
-DuseObjectify=true \
-Dapplication-id=your-app-id \
-Dfilter=com.google.appengine.archetypes:
Datastoreを使う場合はObjectifyを推奨されてるみたいなので、useObjectify
をTrueで指定すれば最初から依存関係に追加してくれます。
ちょっとローディングとか色々やってると以下のような出力になります。
[INFO] Generating project in Interactive mode
[INFO] No archetype defined. Using maven-archetype-quickstart (org.apache.maven.archetypes:maven-archetype-quickstart:1.0)
Choose archetype:
1: remote -> com.google.appengine.archetypes:appengine-flexible-archetype (A basic Java application with Google App Engine flexible.)
2: remote -> com.google.appengine.archetypes:appengine-skeleton-archetype (A skeleton application with Google App Engine)
3: remote -> com.google.appengine.archetypes:appengine-standard-archetype (A basic Java application with Google App Engine Standard)
4: remote -> com.google.appengine.archetypes:endpoints-skeleton-archetype (A skeleton project using Cloud Endpoints Frameworks with Google App Engine Standard)
5: remote -> com.google.appengine.archetypes:guestbook-archetype (A guestbook application with Google App Engine)
6: remote -> com.google.appengine.archetypes:hello-endpoints-archetype (A simple starter application using Cloud Endpoints Frameworks with Google App Engine Standard)
7: remote -> com.google.appengine.archetypes:skeleton-archetype (Archetype with a README about Google App Engine archetypes)
公式の説明を見てもどれを選べば良いのかイマイチ判断が付きかねるのですが、3
でイイと思います。
Cloud Endpointsを使いたい人は4
あたりでしょうか。
ちゃんとみてないのでアレですが、違いがObjectifyを作成時に指定できるかどうかとMockitoのバージョンがSkelton(2
)だと2.0のβになってるくらいの違いでした。
生成されるコードに違いはありません。
というかSpring Bootで動かすので生成されるJavaコードは後で捨てますが。
残りはGroupIDやらArtifactIDやらPackageやら聞かれるので答えていけばOKです。
これでJava8で動くAppEngine SEのソースコードのできあがり。
Hello Worldが入ってるだけですが。
開発環境
IDEAの設定
デフォルトでAppEngineプラグインが入ってるかもしれません。
こちらはDeprecatedになってるので無効にしましょう。
- Google Cloud Toolsプラグインをインストール
- Google App Engineプラグインを無効化
詳細はこちらを参照して下さい。
組み込まれてるのでアンインストールできないと思うので無効です。
そのうちバージョンアップで消えるんじゃないかなと思います。
その他のCloudSDKやらの設定は公式の方に書かれているのを参照してもらえば良いかなと思います。
プロジェクトの作成
適当に空のプロジェクトを作成してください。
そこにImport Moduleします。
プロジェクトのSDKはJava8を指定しておいてください。
モジュールの追加
作成したアプリケーションをIntteliJのプロジェクトにインポートします。
pom.xmlを指定してインポートしてください。
インポートしてProject Structureのウィンドウを閉じるとGAEを勝手に検知して設定するかどうか右下に出てくるのでConfigureしてください。
そして空気を読んで設定を読み込んでローカルサーバやらデプロイの設定をIntelliJ上で実行できるようにしてくれます。
デプロイについてはこの後Edit Configureでプロジェクトの設定などをしないといけません。
デプロイの設定
デプロイを選びます。
プレゼントマークみたいなのを選べばOK。
そうすると下にデプロイの設定やらプロジェクトの設定やらが出てきます。
初回はログインしないといけないのでボタンをポチるとブラウザが開いてログインします。
認証済みだと画像のような感じで所有しているプロジェクトが出てくるので対象のGCPプロジェクトを選択してください。
デプロイオプション
VersionはAuto Generateにしといた方がよさそう。
即トラフィックをデプロイしたバージョンにしたい場合はPromote the deployed version to receive all traffic
をONにすればいいです。
CronやらIndexやらの更新もあるならUpdateほげほげの所もONにするといいでしょう。
Spring Bootにしていく
依存関係の追加
pom.xml
をいじりましょう。
AppEngineはJettyらしいので、Spring BootデフォルトのTomcatを除外する必要があります。
<dependencies>
に追加
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>${spring.boot.version}</version>
<!-- Exclude Tomcat so that it doesn't conflict w/ Jetty server -->
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- Exclude any jul-to-slf4j -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jul-to-slf4j</artifactId>
<scope>provided</scope>
</dependency>
<dependencyManagement>
を追加
<dependencyManagement>
<dependencies>
<dependency>
<!-- Import dependency management from Spring Boot -->
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring.boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<plugins>
に追加
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring.boot.version}</version>
</plugin>
<properties>
に追加
<spring.boot.version>1.5.6.RELEASE</spring.boot.version>
これで後は普通にSpring Boot Applicationを実装していってください。
アーキタイプで生成されたHelloAppEngineとかindex.jspとかは消してしまっても問題ありません。
起動時のバナー出力はOFFにする
Loggingに出るのがウザくなるのでOFFにするのがオススメです。
ONだとこんな感じ。
application.yml
に設定追加しましょう。
spring:
main:
banner-mode: "off"
まとめ
かんそー
何か普通にSpring Bootで開発できそうな雰囲気です。
正直最初ドキュメントとか読んだりリポジトリのソースコード読んだりしててMavenのタスクとか間違ってたりしたんで何なんだよって思いながら1日ほど費やしましたが、ローカルで開発するならこれでいけるかなと思います。
コマンドで起動するならmvn appengine:run
でいけると思います。
またそのうちちゃんとアプリケーション実装してみてもいいかもしれない。
起動時間は?
ほとんど依存関係のない今回のソースコードで初回アクセスでスピンアップして動き始めるまでに10秒くらいかかりますね。
これがどうというのは個人的には何とも言えないので各自判断してください。
(起動の時間をLoggingのリクエスト開始からアプリケーション起動ログが終わるところまでで判断したんだけどこれであってるのかな?)
ちゃんとはかる方法誰か教えてください。
依存関係モリモリにしたらたぶん初回起動が恐ろしく遅くなりそうだからありがちなモノリシックアプリケーションには向いてない気がします。
おまけ
mavenのappengine pluginのデプロイですが、gcloud app
コマンド使ってるんですね。
りぽじとり
今回のソースコードはこちら