Spring Boot + npm + Geb で入力フォームを作ってテストする ( その73 )( Spring Boot を 1.5.14 → 2.0.4 へバージョンアップする )
概要
記事一覧はこちらです。
感想 の続きです。
- 今回の手順で確認できるのは以下の内容です。
- Spring Boot を 1系(1.5.14) → 2系(2.0.4) へバージョンアップします。
参照したサイト・書籍
Spring Boot 2.0 Release Notes
https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-2.0-Release-NotesSpring Boot 2.0 Migration Guide
https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-2.0-Migration-GuideSpring Boot Gradle Plugin Reference Guide
https://docs.spring.io/spring-boot/docs/current/gradle-plugin/reference/html/spring-gradle-plugins/dependency-management-plugin
https://github.com/spring-gradle-plugins/dependency-management-pluginSpring Boot Tomcat Connection Pool
https://www.concretepage.com/spring-boot/spring-boot-tomcat-connection-poolwhy remove "HASH_MAP" pattern on spring boot 2.x
https://github.com/spring-projects/spring-session/issues/1043Better detection of Spring Session store
https://github.com/spring-projects/spring-boot/issues/9683Spring Session - Spring Boot - 2. Spring Boot Configuration
https://docs.spring.io/spring-session/docs/current/reference/html5/guides/boot-jdbc.html#httpsession-jdbc-boot-spring-configurationCould not initialize plugin: interface org.mockito.plugins.MockMaker
https://stackoverflow.com/questions/41956692/could-not-initialize-plugin-interface-org-mockito-plugins-mockmakerThere is a issue, after I downgrade the Mockito version, it disappeared
https://github.com/mockito/mockito/issues/1207Spring Boot Security 2.0
https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-Security-2.0
目次
- build.gradle を変更する
- エラーの出ているクラスを変更する
- application.properties で spring.session.store-type の設定を
hash_map
→jdbc
に変更する(hash_map
はなくなりました) - spring-session-jdbc を追加する
- Build Project(Ctrl+F9)を実行して出るエラーを取り除く
- clean タスク → Rebuild Project → build タスクを実行する
- テストが失敗した原因を調査する
- Tomcat を起動して、起動時に spring-boot-properties-migrator が出力するメッセージに対応する
- gebTest を実行してみる
- ブラウザで画面を表示して入力してみる
- 作成された jar ファイルの中身を確認する
- 本番稼働用ディレクトリに jar ファイルをコピーして動作確認する
- build.gradle から
runtimeOnly("org.springframework.boot:spring-boot-properties-migrator")
を削除する - メモ書き
手順
build.gradle を変更する
build.gradle の以下の点を変更します。
buildscript { ext { group "ksbysample" version "1.0.2-RELEASE" } } plugins { id "java" id "eclipse" id "idea" id "org.springframework.boot" version "2.0.4.RELEASE" id "io.spring.dependency-management" version "1.0.6.RELEASE" id "groovy" id "net.ltgt.errorprone" version "0.0.14" id "checkstyle" id "findbugs" id "pmd" id "com.moowork.node" version "1.2.0" } sourceCompatibility = 1.8 targetCompatibility = 1.8 wrapper { gradleVersion = '4.8.1' distributionType = Wrapper.DistributionType.ALL } [compileJava, compileTestGroovy, compileTestJava]*.options*.compilerArgs = ['-Xlint:all,-options,-processing,-path'] compileJava.options.compilerArgs += [ '-Xep:RemoveUnusedImports:WARN' , '-Xep:ParameterName:OFF' ] // for Doma 2 // JavaクラスとSQLファイルの出力先ディレクトリを同じにする processResources.destinationDir = compileJava.destinationDir // コンパイルより前にSQLファイルを出力先ディレクトリにコピーするために依存関係を逆転する compileJava.dependsOn processResources idea { module { inheritOutputDirs = false outputDir = file("$buildDir/classes/main/") } } configurations { // for Doma 2 domaGenRuntime } checkstyle { configFile = file("${rootProject.projectDir}/config/checkstyle/google_checks.xml") toolVersion = '8.11' sourceSets = [project.sourceSets.main] } findbugs { toolVersion = '3.0.1' sourceSets = [project.sourceSets.main] ignoreFailures = true effort = "max" excludeFilter = file("${rootProject.projectDir}/config/findbugs/findbugs-exclude.xml") } tasks.withType(FindBugs) { reports { xml.enabled = false html.enabled = true } } pmd { toolVersion = "6.5.0" sourceSets = [project.sourceSets.main] ignoreFailures = true consoleOutput = true ruleSetFiles = rootProject.files("/config/pmd/pmd-project-rulesets.xml") ruleSets = [] } repositories { mavenCentral() } dependencyManagement { imports { // mavenBom は以下の URL のものを使用する // https://repo.spring.io/release/org/springframework/boot/spring-boot-starter-parent/2.0.4.RELEASE/ // bomProperty に指定可能な property は以下の URL の BOM に記述がある // https://repo.spring.io/release/org/springframework/boot/spring-boot-dependencies/2.0.4.RELEASE/spring-boot-dependencies-2.0.4.RELEASE.pom mavenBom org.springframework.boot.gradle.plugin.SpringBootPlugin.BOM_COORDINATES } } dependencies { def spockVersion = "1.1-groovy-2.4" def domaVersion = "2.19.2" def lombokVersion = "1.18.0" def errorproneVersion = "2.3.1" def powermockVersion = "1.7.4" def seleniumVersion = "3.13.0" // dependency-management-plugin によりバージョン番号が自動で設定されるもの // Appendix F. Dependency versions ( https://docs.spring.io/spring-boot/docs/2.0.4.RELEASE/reference/html/appendix-dependency-versions.html ) 参照 implementation("org.springframework.boot:spring-boot-starter-web") implementation("org.springframework.boot:spring-boot-starter-thymeleaf") { exclude group: "org.codehaus.groovy", module: "groovy" } implementation("org.springframework.boot:spring-boot-starter-data-jpa") implementation("org.springframework.boot:spring-boot-starter-freemarker") implementation("org.springframework.boot:spring-boot-starter-mail") implementation("org.springframework.boot:spring-boot-starter-security") runtimeOnly("org.springframework.boot:spring-boot-devtools") implementation("org.springframework.session:spring-session-core") implementation("org.springframework.session:spring-session-jdbc") implementation("org.codehaus.janino:janino") implementation("org.apache.tomcat:tomcat-jdbc") testImplementation("org.springframework.boot:spring-boot-starter-test") testImplementation("org.springframework.security:spring-security-test") testImplementation("org.yaml:snakeyaml") testImplementation("org.mockito:mockito-core") // dependency-management-plugin によりバージョン番号が自動で設定されないもの、あるいは最新バージョンを指定したいもの implementation("com.integralblue:log4jdbc-spring-boot-starter:1.0.2") implementation("org.flywaydb:flyway-core:5.1.4") implementation("com.h2database:h2:1.4.192") implementation("com.github.rozidan:modelmapper-spring-boot-starter:1.0.0") implementation("com.google.guava:guava:25.1-jre") implementation("org.apache.commons:commons-lang3:3.7") testImplementation("org.dbunit:dbunit:2.5.4") testImplementation("org.assertj:assertj-core:3.10.0") testImplementation("org.spockframework:spock-core:${spockVersion}") testImplementation("org.spockframework:spock-spring:${spockVersion}") testImplementation("com.google.code.findbugs:jsr305:3.0.2") testImplementation("org.jsoup:jsoup:1.11.3") testImplementation("com.icegreen:greenmail:1.5.7") // for lombok annotationProcessor("org.projectlombok:lombok:${lombokVersion}") compileOnly("org.projectlombok:lombok:${lombokVersion}") // for Doma annotationProcessor("org.seasar.doma:doma:${domaVersion}") implementation("org.seasar.doma:doma:${domaVersion}") domaGenRuntime("org.seasar.doma:doma-gen:${domaVersion}") domaGenRuntime("com.h2database:h2:1.4.192") // for Error Prone ( http://errorprone.info/ ) errorprone("com.google.errorprone:error_prone_core:${errorproneVersion}") compileOnly("com.google.errorprone:error_prone_annotations:${errorproneVersion}") // PowerMock testImplementation("org.powermock:powermock-module-junit4:${powermockVersion}") testImplementation("org.powermock:powermock-api-mockito2:${powermockVersion}") // for Geb + Spock testImplementation("org.gebish:geb-spock:2.1") testImplementation("org.seleniumhq.selenium:selenium-chrome-driver:${seleniumVersion}") testImplementation("org.seleniumhq.selenium:selenium-firefox-driver:${seleniumVersion}") testImplementation("org.seleniumhq.selenium:selenium-support:${seleniumVersion}") testImplementation("org.seleniumhq.selenium:selenium-api:${seleniumVersion}") testImplementation("org.seleniumhq.selenium:selenium-remote-driver:${seleniumVersion}") // for Spring Boot 2.0 Migration runtimeOnly("org.springframework.boot:spring-boot-properties-migrator") } ..........
- buildscript block の以下の点を変更します。
- Web アプリのバージョン番号を
version "1.0.1-RELEASE"
→version "1.0.2-RELEASE"
に変更します。 - Spring Boot のバージョン番号は plugins block の
id "org.springframework.boot"
のところで指定するようになるので、springBootVersion = "1.5.14.RELEASE"
を削除します。
- Web アプリのバージョン番号を
- plugins block の以下の点を変更します。
// plugins {} block 内では ${springBootVersion} が使用できないので、バージョンを直接記述している
のコメントを削除します。id "org.springframework.boot" version "1.5.14.RELEASE"
→id "org.springframework.boot" version "2.0.4.RELEASE"
に変更します。id "io.spring.dependency-management" version "1.0.6.RELEASE"
を追加します。
- 明記しなくても問題ないので
bootRepackage { ... }
を削除します。 - dependencyManagement block の以下の点を変更します。
mavenBom("org.springframework.boot:spring-boot-starter-parent:${springBootVersion}")
→mavenBom org.springframework.boot.gradle.plugin.SpringBootPlugin.BOM_COORDINATES
に変更します。- Appendix F. Dependency versions を見ると Thymeleaf のバージョンが 3.0.9.RELEASE になっているので、以下の5行を削除します。
bomProperty 'thymeleaf.version', '3.0.9.RELEASE'
bomProperty 'thymeleaf-extras-springsecurity4.version', '3.0.2.RELEASE'
bomProperty 'thymeleaf-layout-dialect.version', '2.2.2'
bomProperty 'thymeleaf-extras-data-attribute.version', '2.0.1'
bomProperty 'thymeleaf-extras-java8time.version', '3.0.1.RELEASE'
- dependencies block の以下の点を変更します。
compile(...)
→implementation(...)
に変更します。- Appendix F. Dependency versions を見ると
spring-session
は存在せず、spring-session-core
やspring-session-data-gemfire
のように後ろに-...
が付くようになっていました。implementation("org.springframework.session:spring-session")
→implementation("org.springframework.session:spring-session-core")
に変更します。 - Spring Boot 2 では HikariCP がデフォルトのコネクションプーリングに変わり、Tomcat JDBC Connection Pool はデフォルトでは入りません。今は HikariCP には変更しないので
implementation("org.apache.tomcat:tomcat-jdbc")
を追加して入れるようにします。 testImplementation("org.powermock:powermock-api-mockito:${powermockVersion}")
→testImplementation("org.powermock:powermock-api-mockito2:${powermockVersion}")
に変更します。- Spring Boot 2.0 Migration Guide - Before You Start の記述に従い
runtimeOnly("org.springframework.boot:spring-boot-properties-migrator")
を追加します。
変更後、Gradle Tool Window の左上にある「Refresh all Gradle projects」ボタンをクリックして更新すると、特にエラーは出ずに更新されました。
エラーの出ているクラスを変更する
src/main/java/ksbysample/webapp/bootnpmgeb/config/ApplicationConfig.java
- DataSourceBuilder クラスが import できずエラーが出ていました。import 文を削除した後、Alt+Enter を押して import し直します。
src/main/java/ksbysample/webapp/bootnpmgeb/config/WebMvcConfig.java
WebMvcConfigurerAdapter が非推奨になりました。WebMvcConfigurerAdapter クラスの JavaDoc の説明を読むと WebMvcConfigurer インターフェースに Java 8 のデフォルトメソッドで実装が追加されたので WebMvcConfigurer インターフェースを使用するよう記述されていました。
extends WebMvcConfigurerAdapter
→implements WebMvcConfigurer
に変更します。SpringTemplateEngine クラスが import できずエラーが出ていました。import 文を削除した後、Alt+Enter を押して import class し直します。
src/main/java/ksbysample/webapp/bootnpmgeb/config/WebSecurityConfig.java
- 28. Security から
@Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
の記述が削除されていたので、おそらく無くなったものと思われます。@Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
を削除します。
application.properties で spring.session.store-type の設定を hash_map
→ jdbc
に変更する(hash_map
はなくなりました)
spring.session.store-type
に hash_map
が指定できなくなっていました。実際選択可能な候補を表示させてみると hash_map
がありません。
理由が書かれているのは Better detection of Spring Session store のページのようです。今回は hash_map
→ jdbc
に変更して、spring-session-jdbc を入れることにします。
spring-session-jdbc を追加する
build.gradle に implementation("org.springframework.session:spring-session-jdbc")
を追加します。
dependencies { .......... runtimeOnly("org.springframework.boot:spring-boot-devtools") implementation("org.springframework.session:spring-session-core") implementation("org.springframework.session:spring-session-jdbc") implementation("org.codehaus.janino:janino") ..........
変更後、Gradle Tool Window の左上にある「Refresh all Gradle projects」ボタンをクリックして更新します。
src/main/resources/application.properties に以下の設定を追加します。
spring.session.store-type=jdbc spring.session.jdbc.initialize-schema=embedded spring.session.jdbc.schema=classpath:org/springframework/session/jdbc/schema-h2.sql spring.session.jdbc.table-name=SPRING_SESSION
- 以下の3行を追加します。
spring.session.jdbc.initialize-schema=embedded
spring.session.jdbc.schema=classpath:org/springframework/session/jdbc/schema-h2.sql
spring.session.jdbc.table-name=SPRING_SESSION
spring.session.jdbc.schema
に設定する SQL ファイルはorg.springframework.session:spring-session-jdbc
のライブラリの下を見ると分かります。
Build Project(Ctrl+F9)を実行して出るエラーを取り除く
org.hibernate.validator.constraints.NotEmpty
→ javax.validation.constraints.NotEmpty
に変更する
Ctrl+F9 を押して Build Project を実行すると org.hibernate.validator.constraintsのorg.hibernate.validator.constraints.NotEmptyは非推奨になりました
のメッセージが表示されました。
org.hibernate.validator.constraints.NotEmpty クラスのソースを見ると以下の画像の記述がありますので、javax.validation.constraints.NotEmpty に変更します。
変更したのは以下のソースです。import 文を削除した後、Alt+Enter で import し直しました。
- src/main/java/ksbysample/webapp/bootnpmgeb/web/inquiry/form/InquiryInput01Form.java
- src/main/java/ksbysample/webapp/bootnpmgeb/web/inquiry/form/InquiryInput02FormNotEmptyRule.java
- src/main/java/ksbysample/webapp/bootnpmgeb/web/inquiry/form/InquiryInput03FormNotEmptyRule.java
clean タスク → Rebuild Project → build タスクを実行する
clean タスク → Rebuild Project → build タスクを実行してみると、以下の画像のような結果でした。
- FindBugs で
FindBugs rule violations were found.
のメッセージが表示されました。 147 tests completed, 1 failed
とテストが1件失敗しました。
FindBugs の方は一旦後回しにして、まずはテストが失敗した原因を取り除きます。
テストが失敗した原因を調査する
java.lang.NoSuchMethodError: org.mockito.internal.handler.MockHandlerFactory.createMockHandler(Lorg/mockito/mock/MockCreationSettings;)Lorg/mockito/internal/InternalMockHandler;
build タスクの出力内容では原因が分からないので、Project Tool Window の src/test/groovy/ksbysample から「Run 'Tests in 'ksbysample''」を実行します。
失敗したテストは以下の画像のテストでした。java.lang.NoSuchMethodError: org.mockito.internal.handler.MockHandlerFactory.createMockHandler(Lorg/mockito/mock/MockCreationSettings;)Lorg/mockito/internal/InternalMockHandler;
というエラーメッセージが出ています。
エラーメッセージで検索すると There is a issue, after I downgrade the Mockito version, it disappeared という Issue が見つかりました。PowerMock のバージョンを 2.0.0-beta.5
にすると直るようです。
build.gradle の以下の点を変更します。
dependencies { def spockVersion = "1.1-groovy-2.4" def domaVersion = "2.19.2" def lombokVersion = "1.18.0" def errorproneVersion = "2.3.1" def powermockVersion = "2.0.0-beta.5" def seleniumVersion = "3.13.0"
def powermockVersion = "1.7.4"
→def powermockVersion = "2.0.0-beta.5"
に変更します。
変更後、Gradle Tool Window の左上にある「Refresh all Gradle projects」ボタンをクリックして更新します。
clean タスク → Rebuild Project → build タスクを実行すると、今度は BUILD SUCCESSFUL が出力されました。
Tomcat を起動して、起動時に spring-boot-properties-migrator が出力するメッセージに対応する
Tomcat を起動すると以下のメッセージが表示されました。
また、少し放置していたら、1分毎に無効になったセッションを削除するための DELETE 文が実行されていました。なるほど、spring-session-jdbc だとこういう動作になるんですね。
Key: security.basic.enabled、Reason: The security auto-configuration is no longer customizable.
Spring Boot 2.0 Migration Guide - Security と Spring Boot Security 2.0 を読んだ限りでは、application.properties から security.basic.enabled
は設定できなくなり、設定するなら WebSecurityConfigurerAdapter の継承クラスで設定するとのこと。
試しに src/main/resources/application-develop.properties から security.basic.enabled=false
の設定を削除した後 Tomcat を起動すると、Key: security.basic.enabled
のメッセージは出力されなくなり、
H2 Console(http://localhost:8080/h2-console)にアクセスしても Basic 認証のダイアログは表示されませんでした。
gebTest を実行してみる
gebTest タスクを実行してみると、BUILD SUCCESSFUL のメッセージが出力されました。
ブラウザで画面を表示して入力してみる
smtp4dev を起動した後、Tomcat を起動します。http://localhost:8080/inquiry/input/01/ にアクセスして画面からデータを入力してみます。
完了画面まで表示できました。またメールも問題なく送信されており、
DB のデータも登録されていました。
作成された jar ファイルの中身を確認する
boot-npm-geb-sample-1.0.2-RELEASE.jar を開いてみると BOOT-INF の下に lib ディレクトリが作成されて、その下に外部ライブラリの jar ファイルが格納されていました。1.5系の時と違い、build.gradle に implementation で依存関係を記述しても jar ファイルの生成には問題ありませんでした。
本番稼働用ディレクトリに jar ファイルをコピーして動作確認する
以下の手順で動作することを確認しました。
- C:\webapps\boot-npm-geb-sample\lib の下に boot-npm-geb-sample-1.0.2-RELEASE.jar をコピーする。
- C:\webapps\boot-npm-geb-sample\bat\webapp_startup.bat 内の環境変数 WEBAPP_JAR の値を boot-npm-geb-sample-1.0.2-RELEASE.jar に変更する。
- サービスではなくコマンドプロンプトから webapp_startup.bat を起動する。
- C:\webapps\boot-npm-geb-sample\logs\boot-npm-geb-sample.log の最後に Started Application ... のログが出ることを確認する。
- http://localhost:8080/inquiry/input/01/ にアクセスして画面が表示されることを確認する。
build.gradle から runtimeOnly("org.springframework.boot:spring-boot-properties-migrator")
を削除する
バージョンアップ作業が終わりましたので、build.gradle に追加していた runtimeOnly("org.springframework.boot:spring-boot-properties-migrator")
を削除します。
Spring Boot 2系へのバージョンアップは以上で完了です。
メモ書き
- Spring Boot 2系から Flyway のバージョンが 5系に上がりましたが 、Flyway はバージョンアップ前から 5系を使用していたので今回は特に何もありませんでした。
- Spring Boot 2系は Gradle 4.x 以降のみサポートされるので、Gradle が 3.x 以前の場合には Spring Boot を 2系にバージョンアップする前に Gradle のバージョンを 4.x に上げた方がよさそうです。
- build.gradle の書き方がいろいろ変わります。一番変更が大きいファイルでした。
- Spring Session が地味に仕様が変わっています(build.gradle に指定する artifactId の名前が違う、hash_map がなくなった)。
もう少し続きます。FindBugs で警告が出た箇所の確認、HikariCP への変更、及び Spring Boot Actuator の導入まで試してみる予定です。
履歴
2018/08/03
初版発行。