

JHipsterから学ぶ最近のJava開発事情
こんにちは、ソリューション開発部の瀧口です。
突然ですが、JHipsterをご存知でしょうか?
ご存じない方のためにごく簡単に言うと、サーバーサイド SpringBoot + フロントエンド Angular (1 or 2) という、大変「いまどき」っぽいコードを生成する Yeoman のジェネレーターです。
単にソースコードを生成するだけに留まらず、JHipster はビルドツールや実行環境、果ては SonarQube によるコード品質管理まで整えてくれます。 フロントエンドのビルドは yarn、サーバーサイドは Maven or Gradle が即実行可能な状態で用意され、yarn start と mvnw を実行するだけで、Live Reloading が有効な状態で開発を始めることができるんです。
今回は、JHipster が生成するサーバーサイドの中で、ソースコード以外の部分で個人的に「おっ?」と思ったことについて、あれこれ紹介したいと思います。
前提
今回使用したのは、JHipster v4.0.8 で、以下のオプションで生成しています。
? (1/15) Which *type* of application would you like to create? Monolithic application (recommended for simple projects)
? (2/15) What is the base name of your application? blog
? (3/15) Would you like to install other generators from the JHipster Marketplace? No
? (4/15) What is your default Java package name? jp.co.arksystems.devlog
? (5/15) Which *type* of authentication would you like to use? HTTP Session Authentication (stateful, default Spring Security mechanism)
? (6/15) Which *type* of database would you like to use? SQL (H2, MySQL, MariaDB, PostgreSQL, Oracle, MSSQL)
? (7/15) Which *production* database would you like to use? MySQL
? (8/15) Which *development* database would you like to use? H2 with disk-based persistence
? (9/15) Do you want to use Hibernate 2nd level cache? Yes, with ehcache (local cache, for a single node)
? (10/15) Would you like to use Maven or Gradle for building the backend? Maven
? (11/15) Which other technologies would you like to use? (Press <space> to select, <a> to toggle all, <i> to inverse selection)
? (12/15) Which *Framework* would you like to use for the client? [BETA] Angular 2.x
? (13/15) Would you like to use the LibSass stylesheet preprocessor for your CSS? Yes
? (14/15) Would you like to enable internationalization support? Yes
? Please choose the native language of the application? Japanese
? Please choose additional languages to install English
? (15/15) Besides JUnit and Karma, which testing frameworks would you like to use? Gatling
Gitまわり
VCS は、当然のようにGitです。JHipster のバージョンアップも、自動でブランチを作成してマージする、みたいな操作をしてくれます。
.gitignore
Eclipse/IntelliJ/VS Code の設定ファイルや Windows/OS X 特有のファイルなど、毎回除外するものが最初から書いてあるのはありがたいですね。 SASS を選択した場合はコンパイル後の CSS を除外する設定なども入ります。
.gitattributes
ファイルの改行コードを LF に統一し、テキスト/バイナリの指定も一通り行われています。
コーディングまわり
EditorConfig って知りませんでした。対応しているテキストエディタであれば、インデントや文字コードの統一ができるんですね。 とはいえ、細かいフォーマット指定は(当然ながら)対応しないので、Eclipse / IntelliJ 混在環境の悩みがなくなるわけではなさそうです。
Typescript は tsconfig.json と tslint.json が生成されるので、スタイルが統一できそうです。
Mavenまわり
JHipster では Maven か Gradle かを生成時に選べるのですが、私は Maven 派なので。。。
オプションの選択にもよりますが、Maven では1000行ほどの pom.xml が、Gradle の方は 200行ほどの build.gradle + gradle/xxx.gradle 10個程度が生成されます。
Maven Wrapper
Maven v.s. Gradle 戦争の中で、何度「Gradleは gradlew で即実行できる」の破壊力にやられたことか。 何度「Maven のバージョン違う(からビルドできない)」を乗り越えてきたことか。。。
だがしかし、今や我々にもあるのだよ。この mvnw がな!!!
はい。というわけで Maven Wrapper です。 Maven 使うならもう絶対入れましょう。Maven Wrapper を既存のMavenプロジェクトに入れるには
mvn -N io.takari:maven:wrapper
とするだけですよ。
POM全体像
上からざっと眺めてみると、こんな構成になっています。
- 親 POM に spring-boot-starter-parent
- パッケージングは war (src/main/webappディレクトリもある)
- たくさんの properties
- たくさんの dependencies
- ビルドライフサイクルにたくさんのプラグインを仕込む build
- dev, prod 等複数の profiles
これらを詳しく見てみましょう。
親POM指定の parent
SpringBootの 流儀にのっとり、parentがspring-boot-starter:1.5.2.RELEASE です。SpringBoot およびSpring 周りの依存jarバージョンは、これで解決されています。特段変なことはされてない、いたって普通の SpringBoot プロジェクトですね、ここは。
WAR指定の packaging
ここで「おっ?」ってなります。jar ではなく war です。とはいっても Executable JAR を捨てているわけではなく、後述する本番向けビルドでは Fully Executable な WAR が生成されます。
フロントエンドのファイルは Java のクラスパス上に存在する必要はないので src/main/webapp に置き、トランスパイル後の生成物がうまく war に含まれるよう、ビルド設定がなされています。
たくさんの properties
主に spring-boot-starter-parent がもたらす spring-boot-starter-dependencies に書かれていない依存 JAR のバージョン、Maven プラグインのバージョンが定義されています。
project.testresult.directory が定義されているのは、テストレポートをフロントエンド側と同じ場所に出力させるためですね。その辺に集約されたものを、sonar.** の設定で SonarQube に読ませるような設定にされています。
たくさんの dependencies
たくさんありますので、目に付いたものだけ。
JHipster
JHipster 自身の AutoConfiguration 含め、本番環境でのみ有効化されるキャッシュ制御フィルターなどいくつかのユーティリティがある、小さなモジュールです。
Dropwizard Metrics
実行中のメトリクスを収集する Dropwizard Metrics が入っています。DBコネクションプールに HikariCPが選ばれているのも、Dropwizard Metrics に対応しているからでしょうか。
Spring と統合する metrics-spring も用意されており、JHipster は実行時間計測用のアノテーションを付けた状態で Controller を生成します。
Swagger
REST API の設計、テスト、ドキュメント生成に力を発揮する便利なやつ、Swagger です。JHipster では swagger プロファイルで有効になります。
Ehcache
JSR-107 javax.cache API の実装 Ehcache ですね。hibernate-jcache で使われています。
Liquibase
Ruby on Rails で使われる、Active Recordのmigration みたいなことをしてくれる、データベースのスキーマ管理ツールです。昔「Evolutionary Database Design (データベースの進化的設計)」という言葉が出てきたときからありましたね。
JHipster では、テストは SQLite、実行時は MySQL、のように異なるデータベース製品を同時に扱うので、DDL 文そのものではなく、DB 非依存でスキーマ管理できる Liquibase のようなツールが必要になるのでしょう。 Yeoman でモデルを生成するコマンドを行ったときには、Java/Typescript のみならず、Liquibase のチェンジセットも生成される等、JHipster に深く統合されています。
MapStruct
Entity と DTO の Mapper を、Interface とアノテーションから自動生成するものです。現在のバージョンは Lombok と互換性が無いようで、「あれ、Lombok が無いな?」と思ったらこんなところに理由があったのか、って感じです。 次バージョンの1.2.0では Lombok と共存できるようなので、おそらく JHipster にも Lombok が入るんじゃないでしょうか。と思っていましたが、コミッターが相当な Lombok 嫌いな模様・・・ 確かに特定の IDE で特定のプラグインが必要になるから、という理由は納得感ありますね。必要なら自分で追加しろってことで。
Spring Boot
spring-boot-actuator を初め、良いものは大体入っている印象です。
spring-boot-starter-tomcat が外され、代わりに spring-boot-starter-undertow が使われています。 パフォーマンスが良いのと、Tomcat 8 でキャッシュ周りのエラーが起こるのが理由みたいですね。 Issue #2948 で移行を試みたが Windows の呪いで諦め、再挑戦した Issue #4054 で無事にマージされたあたり涙無しでは語れない。
おもてなし build
コミッターの几帳面さがにじみ出てきます。きっとA型ですね。
sortpom-maven-plugin
POM の要素を名前順にソートしてくれるプラグイン。verify フェーズに紐づけられています。
JHipster が生成する POM はソートされてないので、リリース前に突然 diff が出たりしないよう、最初に mvn verify してからコミットするのがオススメ。
maven-resources-plugin
普段使うものですが、*.xm1 と *.yml の # で囲まれた文字列を置換する設定が入っています。 application.yml の spring.profiles.active を、Maven Profile を元に設定するようになっています。
普通の Spring Boot アプリケーションのように、実行時に外から(jarと同じディレクトリに置いた application.yml など)で上書きすることも可能ですので、あくまで初期値ということで。
jacoco-maven-plugin sonar-maven-plugin
テストカバレッジが計測されるようになっています。sonar はライフサイクルにバインドされていないので、mvn clean test sonar:sonar で実行する必要がありますね。
SonarQube サーバーがない場合でも、JHipster が Docker コンテナ設定を生成してくれるので、すぐに用意できます。
spring-boot-maven-plugin
parent が spring-boot-starter なので本来不要ですが、の上書きをしています。Linux 環境でデーモン起動できる Fully Executable Jar になるよう true にされてます。
※ Executable Jar は java -jar hoge.jar で実行できるもの。Fully Executable Jar は ./hoge.jar で実行できるもの、と理解するとよいです
docker-maven-plugin
ビルド成果物を Docker コンテナに配備して実行できるようにしています。Windows で開発していると、正直あまり馴染みがないです、Docker。Vagrant は使うんですけどね。
複数の profiles
通常はデフォルトの dev、リリースビルドするときは prod、IDE 使わない派は cc を、必要に応じて使い分ける感じです。
まとめ
以上ざっくりと JHipster が生成するものを見てきましたが、いかがでしょうか。
私個人の感想として、これまで知らなかったもの(Dropwizard Metrics、Mapstruct)、知っていたけど検証してなかったもの(Liquibase、Docker)が投入されていて、サーバーサイドの進化を感じます。
JHipster そのものを実案件に投入するかはもうちょっと検証が必要ですが、JHipster で使われている要素のうちいくつかは、そのまま既存プロジェクトにも適用できそうです。(Maven Wrapper とかね!)
皆様も自身の知識をアップデートする機会だと思って、JHipster に触ってみてはいかがでしょうか。新しい発見がきっとあると思います。