八 月
30
水曜日
2017

Spring Bootにおける外部設定値のプロパティ名誤り検知について

Spring Bootでは @ConfigurationProperties アノテーションを使用した 型安全なプロパティ定義 によってプロパティ型の保証や BeanValidation によるプロパティ値の検証などを行うことができるため、値の誤りについては検出しやすい環境が整っている。

一方、application.yml(properties)に定義したプロパティ名と@ConfigurationPropertiesを付与したクラスのプロパティ名の不一致のケース(プロパティ名誤り)については気づき難いため、これ検知する方法を調べた。


背景

Spring Bootはバージョンアップの際に@ConfigurationPropertiesを付与したクラスのプロパティ名が変更されることが多々ある。
当該プロパティが

  • @NotNullが付与されておらず必須プロパティではない
  • 定義されなかった場合はデフォルト値が適用される。

である場合、application.yml上に旧プロパティ名で定義された値は当然有効にならず、警告・エラーの類いのログも出力されず、静かにデフォルト値が適用されアプリケーションが動作することになる。

コンフィグレーションメタデータ

Spring Boot関連プロダクトのjarにはコンフィグレーションメタデータ(META-INF/spring-configuration-metadata.json)が含まれている。
メタデータには以下情報が定義されている。

  • プロパティ名
  • @ConfigurationPropertiesが付与されているクラス名
  • デフォルト値
  • deprecationなどの情報

この情報を利用することでプロパティ名誤りを検出することが出来そうだ。

自プロジェクトでもコンフィグレーションメタデータを出力する

以下のSpring Boot公式ドキュメントに記述があるとおり自プロジェクトにSpring Boot Configuration Processorを組み込む事で自プロジェクト用のコンフィグレーションメタデータを出力することができる。

メタデータを出力するようbuild.gradleに以下の修正を行う。

porpdepsプラグイン

optionalの依存定義を行うため、propdeps-pluginを追加する。

buildscript {
  repositories {
    maven { url 'http://repo.spring.io/plugins-release' }
  }
  dependencies {
    classpath('io.spring.gradle:propdeps-plugin:0.0.9.RELEASE')
  }
}

利用環境に応じて必要なpropdepsプラグインを適用する。

apply plugin: 'propdeps'
// Gradle maven pluginを使う場合
apply plugin: 'propdeps-maven'
// IntelliJ IDEAを使う場合
apply plugin: 'propdeps-idea'
// Eclipseを使う場合
apply plugin: 'propdeps-eclipse'

Spring Boot Configuration Processor

依存関係にSpring Boot Configuration Processorを追加。

dependencies {
  optional('org.springframework.boot:spring-boot-configuration-processor')
}

コンパイル前にリソース処理が行われるようにする。

compileJava.dependsOn(processResources)

以上でCLIからgradleでビルドした際に自プロジェクト用のMETA-INF/spring-configuration-metadata.jsonが出力されるようになる。

IntelliJ IDEAとコンフィグレーションメタデータ

ビルド時にコンフィグレーションメタデータを出力する

CLIからGradleでビルドするとコンフィグレーションメタデータが出力されるようになったが、 IntelliJ IDEA上のビルドでコンフィグレーションメタデータを出力するためには加えてAnnotation Processingを有効にする必要がある。

Preferences… Build, Execution, Deployment Compiler Annotation Processors から Enable annotation processingにチェックを付けてAnnotation Processingを有効にする。

Ultimate EdtionとCommunity Edition

IntelliJ IDEAのUltimate EditionはSpring BootのFramework Supportが入っているため、 application.yml(properties)を編集する際にコンフィグレーションメタデータを読み取り、存在しないプロパティ名や不正なプロパティ値は強調表示してくれる。
一方Community Editionはというと残念ながらSpring BootのFramework Supportが入っていないためコンフィグレーションメタデータを利用した強調表示は行われない。

IDEでは無い他のなにか

とりあえずUltimate Editionが使えればIDE上の目視でコンフィグレーションをチェックすればプロパティ名誤りを防ぐことはできそうだ。
(Ultimate Editionが無い環境はSpring Tool Suiteで代替)

ただ本来はIDEに依存しないコンパイル時のGradleのタスクやSonarのLintでチェックしたいところではあるが適当なものを見つけることはできなかった。 Spring Bootのバージョンアップをアグレッシブに追い続けるような環境だったらそのようなGradleタスクやSonarのLintを作った方が良いのかもしれない。