Spring Boot 1.4.x の Web アプリを 1.5.x へバージョンアップする ( その3 )( Run 'All Tests' with Coverage 実行時に出るエラーを解消する )
概要
記事一覧はこちらです。
Spring Boot 1.4.x の Web アプリを 1.5.x へバージョンアップする ( その1 )( 概要 ) の続きです。
- 今回の手順で確認できるのは以下の内容です。
- Run ‘All Tests’ with Coverage 実行時に出るエラーの解消
参照したサイト・書籍
目次
手順
java.lang.IllegalStateException: Failed to load ApplicationContext
java.lang.IllegalStateException: Failed to load ApplicationContext
の下に出力されるメッセージの内、Caused by:
から始まるエラーメッセージは以下のものでした。
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'webSecurityConfig': Unsatisfied dependency expressed through method 'setContentNegotationStrategy' parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration$EnableWebMvcConfiguration': Invocation of init method failed; nested exception is java.lang.IllegalStateException: Found unexpected validator configuration. A Spring Boot MVC validator should be registered as bean named 'mvcValidator' and not returned from WebMvcConfigurer.getValidator()
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration$EnableWebMvcConfiguration': Invocation of init method failed; nested exception is java.lang.IllegalStateException: Found unexpected validator configuration. A Spring Boot MVC validator should be registered as bean named 'mvcValidator' and not returned from WebMvcConfigurer.getValidator()
Caused by: java.lang.IllegalStateException: Found unexpected validator configuration. A Spring Boot MVC validator should be registered as bean named 'mvcValidator' and not returned from WebMvcConfigurer.getValidator()
Spring Boot MVC validator は mvcValidator
という名前の Bean で登録されているべきなのに、WebMvcConfigurer.getValidator()
が返さない、ということのようです。
例外に出力されているソースを追ってみると、org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration.EnableWebMvcConfiguration#afterPropertiesSet でこのメッセージを出力していることが確認できます。getValidator() == null
でないと Assert に引っかかります。
getValidator()
は org.springframework.web.servlet.config.annotation.DelegatingWebMvcConfiguration#getValidator のことで、以下のコードです。
configurers.getValidator()
は org.springframework.web.servlet.config.annotation.WebMvcConfigurerComposite#getValidator のことで、以下のコードです。このメソッドが null を返さないのでエラーになるようですね。
デバッガで確認してみると、確かに null ではなく LocalValidatorFactoryBean を返しています。
自分で実装したコードを見ると、確かに Validator インターフェースの Bean は mvcValidator
ではなく validator
という名前にしています。
そして validator Bean を ksbysample.webapp.lending.config.WebMvcConfig#getValidator で返しています。
Spring Boot 1.3.x の Web アプリを 1.4.x へバージョンアップする ( その20 )( 気になった点を修正する ) の記事で ValidationMessages_ja_JP.properties をやめて messages.properties に1本化するために書いたものでした。
ここまでの調査から対応方法を考えると、以下のようにすれば良い気がします。
- ksbysample.webapp.lending.config.WebMvcConfig#getValidator は null を返さないといけないようなので、ksbysample.webapp.lending.config.WebMvcConfig 自体は削除する。
- validator Bean ではなく mvcValidator Bean にする。
“mvcValidator” で検索してみると org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration.EnableWebMvcConfiguration#mvcValidator に mvcValidator Bean を取得して mvcValidator Bean を生成する?、というよく分からないコードがありました。
Spring Boot 1.4.6 を使用している時のコードに戻してみると、org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration.EnableWebMvcConfiguration#mvcValidator は 1.5.3 と同じでした。
org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration.EnableWebMvcConfiguration#afterPropertiesSet は存在しませんでした。
おそらく 1.4 の頃から mvcValidator という名前の Bean として登録しておけばよいだけで、WebMvcConfigurerAdapter の継承クラスで getValidator メソッドを Override する必要はなかった、のではないかと思います。
上に書いた2点の対応方法で良さそうなので、コードを修正します。
まず src/main/java/ksbysample/webapp/lending/config/WebMvcConfig.java を削除します。
次に src/main/java/ksbysample/webapp/lending/config/ApplicationConfig.java を リンク先の内容 に変更します。
最後に以下のクラスのフィールド private final Validator validator;
→ private final Validator mvcValidator;
に変更します。
- src/main/java/ksbysample/webapp/lending/web/springmvcmemo/BeanValidationGroupController.java
- src/test/java/ksbysample/webapp/lending/values/validation/ValuesEnumValidatorTest.java
コードを修正したら clean タスク → Rebuild Project → build タスクを実行してみます。今度は “BUILD SUCCESSFUL” が表示されて成功しました。
Project Tool Window の src/test から「Run ‘All Tests’ with Coverage」も実行してみます。こちらも無事全てのテストが成功しました。
Hibernate Validator を使用しているところで messages.properties に記述した日本語のメッセージが使用されるか確認します。
bootRun で Tomcat を起動した後、Hibernate Validator の @NotBlank
アノテーションで入力チェックをしている
http://localhost:8080/springMvcMemo/beanValidationGroup にアクセスします。
「データ更新」ボタンをクリックすると、日本語のメッセージ「必須の入力項目です。」が表示されました。
mvcValidator Bean をコメントアウトしてから Tomcat を再起動して同じ操作をしてみると、
今度は英語のメッセージが表示されました。mvcValidator Bean を定義するだけで messages.properties の日本語メッセージが使用されるようになるようです。
次回は。。。
1.5 系ではこう書くべきという点があるか確認し、変更した方がよいところを修正します。
ソースコード
ApplicationConfig.java
@Bean public Validator mvcValidator() { LocalValidatorFactoryBean localValidatorFactoryBean = new LocalValidatorFactoryBean(); localValidatorFactoryBean.setValidationMessageSource(this.messageSource); return localValidatorFactoryBean; }
- メソッド名を
validator
→mvcValidator
に変更します。
履歴
2017/05/17
初版発行。
2017/05/20
* http://localhost:8080/springMvcMemo/beanValidationGroup での動作確認を追加しました。