JHipsterから学ぶ最近のJava開発事情

2017年3月15日Apache Maven,Java,JHipster,Spring Boot,プログラミング,開発環境・ツール

Welcome, Java Hipster

こんにちは、ソリューション開発部の瀧口です。
突然ですが、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 に触ってみてはいかがでしょうか。新しい発見がきっとあると思います。

  • Zabbix Enterprise Appliance
  • 低コスト・短納期で提供するまるごとおまかせZabbix