かんがるーさんの日記

最近自分が興味をもったものを調べた時の手順等を書いています。今は Spring Boot をいじっています。

Spring Boot 1.5.x の Web アプリを 2.0.x へバージョンアップする ( その3 )( build.gradle を変更する )

概要

記事一覧はこちらです。

Spring Boot 1.5.x の Web アプリを 2.0.x へバージョンアップする ( その2 )( Gradle を 3.5 → 4.10 にバージョンアップする ) の続きです。

  • 今回の手順で確認できるのは以下の内容です。
    • build.gradle を変更します。
      • Spring Initializr で 2.0.4 のプロジェクトを作成して、変更した方がよい点があれば反映します。
      • Spring Boot のバージョンを 1.5.4 → 2.0.4 に変更します。
      • BOM を Spring IO Platform のものから Spring Boot のものに変更します。
      • ライブラリは最新バージョンにアップデートします。

参照したサイト・書籍

目次

  1. Spring Initializr で 2.0.4 のプロジェクトを作成する
  2. build.gradle を変更する
  3. Rebuild Project でエラーの出るクラスを修正する
    1. src/main/java/ksbysample/webapp/lending/config/ApplicationConfig.java
    2. src/main/java/ksbysample/webapp/lending/config/WebMvcConfig.java
    3. src/main/java/ksbysample/webapp/lending/config/WebSecurityConfig.java
    4. src/main/java/ksbysample/webapp/lending/security/LendingUserDetailsService.java
    5. src/main/java/ksbysample/webapp/lending/web/WebappErrorController.java
    6. org.hibernate.validator.constraintsのorg.hibernate.validator.constraints.NotBlankは非推奨になりました
    7. org.springframework.web.servlet.mvc.method.annotationのorg.springframework.web.servlet.mvc.method.annotation.AbstractJsonpResponseBodyAdviceは非推奨になりました
  4. build タスク実行時に出るエラーを修正する
    1. An unhandled exception was thrown by the Error Prone static analysis plugin. @Data
    2. 警告:[deprecation] org.mockitoのMatchersは推奨されません
    3. 警告:[deprecation] FilesのtoString(File,Charset)は推奨されません
    4. 警告:[deprecation] MockMvcRequestBuildersのfileUpload(String,Object...)は推奨されません
  5. 次回は。。。

手順

Spring Initializr で 2.0.4 のプロジェクトを作成する

Spring Initializr で 2.0.4 のプロジェクトを作成して、生成された build.gradle を見て反映した方が良い点があるか確認します。

f:id:ksby:20180902103149p:plain f:id:ksby:20180902103249p:plain f:id:ksby:20180902103400p:plain f:id:ksby:20180902103451p:plain f:id:ksby:20180902103825p:plain f:id:ksby:20180902103926p:plain f:id:ksby:20180902104018p:plain f:id:ksby:20180902104258p:plain f:id:ksby:20180902104339p:plain

以下の build.gradle が作成されました。

buildscript {
    ext {
        springBootVersion = '2.0.4.RELEASE'
    }
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
    }
}

apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'

group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = 1.8

repositories {
    mavenCentral()
}


dependencies {
    compile('org.springframework.boot:spring-boot-starter-data-redis')
    compile('org.springframework.boot:spring-boot-starter-freemarker')
    compile('org.springframework.boot:spring-boot-starter-mail')
    compile('org.springframework.boot:spring-boot-starter-security')
    compile('org.springframework.boot:spring-boot-starter-thymeleaf')
    compile('org.springframework.boot:spring-boot-starter-web')
    compile('org.springframework.session:spring-session-data-redis')
    runtime('org.springframework.boot:spring-boot-devtools')
    compileOnly('org.projectlombok:lombok')
    testCompile('org.springframework.boot:spring-boot-starter-test')
    testCompile('org.springframework.security:spring-security-test')
}

反映した方がよいのは Spring Boot 2.0 Migration Guide に書いてある apply plugin: 'io.spring.dependency-management' だけでした。これは Spring Boot 2.0 Migration Guide に従って変更するので、Spring Initializr で生成された build.gradle からは何も反映しません。

build.gradle を変更する

以下の方針で変更します。

buildscript {
    ext {
        group "ksbysample"
        version "2.0.4-RELEASE"
    }
    repositories {
        mavenCentral()
        maven { url "https://repo.spring.io/release/" }
        maven { url "https://plugins.gradle.org/m2/" }
    }
}

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 "checkstyle"
    id "findbugs"
    id "pmd"
    id "net.ltgt.errorprone" version "0.0.16"
    id "de.undercouch.download" version "3.4.3"
}

sourceCompatibility = 1.8
targetCompatibility = 1.8

wrapper {
    gradleVersion = "4.10"
    distributionType = Wrapper.DistributionType.ALL
}

[compileJava, compileTestGroovy, compileTestJava]*.options*.encoding = "UTF-8"
[compileJava, compileTestGroovy, compileTestJava]*.options*.compilerArgs = ["-Xlint:all,-options,-processing,-path"]
compileJava.options.compilerArgs += [
        "-Xep:RemoveUnusedImports:WARN"
        , "-Xep:InsecureCryptoUsage:OFF"
]

// for Doma 2
// JavaクラスとSQLファイルの出力先ディレクトリを同じにする
processResources.destinationDir = compileJava.destinationDir
// コンパイルより前にSQLファイルを出力先ディレクトリにコピーするために依存関係を逆転する
compileJava.dependsOn processResources

idea {
    module {
        inheritOutputDirs = false
        outputDir = file("$buildDir/classes/main/")
    }
}

springBoot {
    buildInfo()
}

configurations {
    // for Doma 2
    domaGenRuntime
}

checkstyle {
    configFile = file("${rootProject.projectDir}/config/checkstyle/google_checks.xml")
    toolVersion = "7.8.1"
    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 = "5.8.1"
    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) {
            // Spring Boot の BOM に定義されているバージョンから変更する場合には、ここに以下のように記述する
            // bomProperty "thymeleaf.version", "3.0.9.RELEASE"
        }
    }
}

dependencies {
    def jdbcDriver = "org.postgresql:postgresql:42.2.4"
    def spockVersion = "1.1-groovy-2.4"
    def domaVersion = "2.19.3"
    def lombokVersion = "1.18.2"
    def errorproneVersion = "2.3.1"
    def powermockVersion = "2.0.0-beta.5"

    // dependency-management-plugin によりバージョン番号が自動で設定されるもの
    // Appendix A. Dependency versions ( http://docs.spring.io/platform/docs/current/reference/htmlsingle/#appendix-dependency-versions ) 参照
    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.thymeleaf.extras:thymeleaf-extras-springsecurity4")
    implementation("org.thymeleaf.extras:thymeleaf-extras-java8time")
    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")
    implementation("org.springframework.boot:spring-boot-starter-data-redis")
    implementation("org.springframework.boot:spring-boot-starter-amqp")
    implementation("org.springframework.boot:spring-boot-devtools")
    implementation("org.springframework.session:spring-session-core")
    implementation("org.springframework.session:spring-session-data-redis")
    implementation("org.springframework.retry:spring-retry")
    implementation("com.fasterxml.jackson.datatype:jackson-datatype-jsr310")
    implementation("com.fasterxml.jackson.dataformat:jackson-dataformat-xml")
    implementation("org.apache.commons:commons-lang3")
    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")
    runtimeOnly("org.springframework.boot:spring-boot-properties-migrator")

    // dependency-management-plugin によりバージョン番号が自動で設定されないもの、あるいは最新バージョンを指定したいもの
    runtimeOnly("${jdbcDriver}")
    implementation("com.integralblue:log4jdbc-spring-boot-starter:1.0.2")
    implementation("org.simpleframework:simple-xml:2.7.1")
    implementation("com.univocity:univocity-parsers:2.7.5")
    implementation("com.google.guava:guava:26.0-jre")
    testImplementation("org.dbunit:dbunit:2.5.4")
    testImplementation("com.icegreen:greenmail:1.5.8")
    testImplementation("org.assertj:assertj-core:3.11.0")
    testImplementation("com.jayway.jsonpath:json-path:2.4.0")
    testImplementation("org.jsoup:jsoup:1.11.3")
    testImplementation("cglib:cglib-nodep:3.2.7")
    testImplementation("org.spockframework:spock-core:${spockVersion}")
    testImplementation("org.spockframework:spock-spring:${spockVersion}")
    testImplementation("com.google.code.findbugs:jsr305:3.0.2")

    // for lombok
    annotationProcessor("org.projectlombok:lombok:${lombokVersion}")
    compileOnly("org.projectlombok:lombok:${lombokVersion}")
    testCompileOnly("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("${jdbcDriver}")

    // 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}")
}

..........
  • 先頭に記述していた以下の2行は buildscript block の中の ext block に移動します。また version は 2.0.4-RELEASE に変更します。これにより buildscript block が一番上になります。
    • group 'ksbysample'
    • version '1.5.4-RELEASE'version '2.0.4-RELEASE'
  • buildscript block の以下の点を変更します。
    • ext block から springBootVersion = '1.5.4.RELEASE' を削除します。Spring Boot のバージョンは plugins block 内の org.springframework.boot プラグインで指定します。
    • repositories block 内で jcenter()mavenCentral() に変更します。
    • plugins block を書くように変更すると dependencies block は不要になるので削除します。
  • プラグインの書き方を apply plugin: ... から plugins block に変更します。ここは変更内容が大きいので詳細は上を見てください。Gradle plugin のバージョンは https://plugins.gradle.org/ で検索して調べます。
  • springBoot { buildInfo() } を追加します。
  • repositories block で jcenter()mavenCentral() に変更します。
  • dependencyManagement block の以下の点を変更します。
    • mavenBom("io.spring.platform:platform-bom:Brussels-SR3")mavenBom(org.springframework.boot.gradle.plugin.SpringBootPlugin.BOM_COORDINATES) に変更します。
    • Spring Boot の BOM では guava は記述されていないので、bomProperty 'guava.version', '21.0' を削除します。
    • Thymeleaf 関連のライブラリは Spring Boot の BOM に最新バージョン(3.0.9.RELEASE等)が記述されているので、以下の5行を削除します。
      • bomProperty 'thymeleaf.version', '3.0.6.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.0.RELEASE'
  • bootRepackage タスクは書かなくても動作するので削除します。
  • dependencies block の以下の点を変更します。
  • ライブラリのバージョンを最新にします。ライブラリの最新バージョンは主に https://mvnrepository.com/ で調べます(一部ライブラリの GitHub ページ等を見る必要あり)。
    • def jdbcDriver = "org.postgresql:postgresql:42.1.1"def jdbcDriver = "org.postgresql:postgresql:42.2.4"
    • def domaVersion = "2.16.1"def domaVersion = "2.19.3"
    • def lombokVersion = "1.16.16"def lombokVersion = "1.18.2"
    • def errorproneVersion = "2.0.15"def errorproneVersion = "2.3.1"
    • def powermockVersion = "1.6.6"def powermockVersion = "2.0.0-beta.5"
    • implementation("com.integralblue:log4jdbc-spring-boot-starter:1.0.1")implementation("com.integralblue:log4jdbc-spring-boot-starter:1.0.2")
    • implementation("com.univocity:univocity-parsers:2.4.1")implementation("com.univocity:univocity-parsers:2.7.5")
    • testImplementation("org.dbunit:dbunit:2.5.3")testImplementation("org.dbunit:dbunit:2.5.4")
    • testImplementation("com.icegreen:greenmail:1.5.5")testImplementation("com.icegreen:greenmail:1.5.8")
    • testImplementation("org.assertj:assertj-core:3.8.0")testImplementation("org.assertj:assertj-core:3.11.0")
    • testImplementation("com.jayway.jsonpath:json-path:2.2.0")testImplementation("com.jayway.jsonpath:json-path:2.4.0")
    • testImplementation("org.jsoup:jsoup:1.10.3")testImplementation("org.jsoup:jsoup:1.11.3")
    • testImplementation("cglib:cglib-nodep:3.2.5")testImplementation("cglib:cglib-nodep:3.2.7")
  • guava はバージョン番号を指定する必要があるので、以下のように変更します。
    • implementation("com.google.guava:guava")implementation("com.google.guava:guava:26.0-jre")
  • Spring Boot + npm + Geb で入力フォームを作ってテストする ( その73 )( Spring Boot を 1.5.14 → 2.0.4 へバージョンアップする ) の記事で実施した以下の点も反映します。
    • implementation("org.springframework.session:spring-session")implementation("org.springframework.session:spring-session-core") に変更します。
    • implementation("org.springframework.session:spring-session-data-redis") を追加します。
    • implementation("org.apache.tomcat:tomcat-jdbc") を追加します。
    • testImplementation("org.powermock:powermock-api-mockito:${powermockVersion}")testImplementation("org.powermock:powermock-api-mockito2:${powermockVersion}") に変更します。
    • runtimeOnly("org.springframework.boot:spring-boot-properties-migrator") を追加します。

変更後、Gradle Tool Window の左上にある「Refresh all Gradle projects」ボタンをクリックして更新すると、特にエラーは出ずに更新されました。

Rebuild Project でエラーの出るクラスを修正する

clean タスク実行 → Rebuild Project 実行 をするとエラーが出るので修正します。

src/main/java/ksbysample/webapp/lending/config/ApplicationConfig.java

f:id:ksby:20180902213318p:plain

  • DataSourceBuilder クラスが import できずエラーが出ていました。import 文を削除した後、Alt+Enter を押して import し直します。

src/main/java/ksbysample/webapp/lending/config/WebMvcConfig.java

f:id:ksby:20180902212655p:plain

  • WebMvcConfigurerAdapter が非推奨になりました。WebMvcConfigurerAdapter クラスの JavaDoc の説明を読むと WebMvcConfigurer インターフェースに Java 8 のデフォルトメソッドで実装が追加されたので WebMvcConfigurer インターフェースを使用するよう記述されていました。extends WebMvcConfigurerAdapterimplements WebMvcConfigurer に変更します。
  • SpringTemplateEngine クラスが import できずエラーが出ていました。import 文を削除した後、Alt+Enter を押して import class し直します。

src/main/java/ksbysample/webapp/lending/config/WebSecurityConfig.java

f:id:ksby:20180902222047p:plain

  • 28. Security から @Order(SecurityProperties.ACCESS_OVERRIDE_ORDER) の記述が削除されていたので、おそらく無くなったものと思われます。@Order(SecurityProperties.ACCESS_OVERRIDE_ORDER) を削除します。
  • コンストラクタの引数 userDetailsService で赤波線が出ています。IntelliJ IDEA で原因を表示させると Autowired 可能な Bean が2種類以上あるので、その警告でした。 f:id:ksby:20180902223756p:plain コンストラクタの引数を UserDetailsService userDetailsService@Qualifier("lendingUserDetailsService") UserDetailsService userDetailsService に変更します。

src/main/java/ksbysample/webapp/lending/security/LendingUserDetailsService.java

エラーは出ていませんが、クラス名が "~Service" なのに @Component アノテーションなのは違和感があったので、@Component@Service アノテーションに変更します。

src/main/java/ksbysample/webapp/lending/web/WebappErrorController.java

f:id:ksby:20180902230106p:plain

  • ErrorController クラスが import できずエラーが出ていました。import 文を削除した後、Alt+Enter を押して import class し直します。

org.hibernate.validator.constraintsのorg.hibernate.validator.constraints.NotBlankは非推奨になりました

f:id:ksby:20180903022520p:plain

  • org.hibernate.validator.constraints.NotEmpty は非推奨になったので javax.validation.constraints.NotEmpty に変更します。import 文を削除した後、Alt+Enter で import し直します。
  • 修正したのは以下のソースです。
    • src/main/java/ksbysample/webapp/lending/web/springmvcmemo/EditFormChecker.java
    • src/main/java/ksbysample/webapp/lending/web/springmvcmemo/SendmailFormChecker.java

org.springframework.web.servlet.mvc.method.annotationのorg.springframework.web.servlet.mvc.method.annotation.AbstractJsonpResponseBodyAdviceは非推奨になりました

f:id:ksby:20180903023004p:plain

  • org.springframework.web.servlet.mvc.method.annotation.AbstractJsonpResponseBodyAdvice が非推奨になっていました。AbstractJsonpResponseBodyAdvice のソースを見ると、Spring Framework 5.1 で削除する予定なので CORS を使用するよう書かれています。JavascriptJSONP で呼んでいるところも修正する必要があるので、今は一旦無視します。

    f:id:ksby:20180903023158p:plain

build タスク実行時に出るエラーを修正する

An unhandled exception was thrown by the Error Prone static analysis plugin. @Data

f:id:ksby:20180904002622p:plain

error-prone により An unhandled exception was thrown by the Error Prone static analysis plugin. というメッセージが出て @Data アノテーションで引っかかりました。もう少しエラーが発生している詳細な原因が知りたいので、コマンドプロンプトから gradlew --stacktrace build コマンドを実行します。

f:id:ksby:20180904003108p:plain

引っかかっている BugPattern がすごく見やすくなっていました。いつの間に。。。 今回は ParameterName で引っかかっているようなので、これを無効にします。build.gradle を以下のように変更します。

[compileJava, compileTestGroovy, compileTestJava]*.options*.encoding = "UTF-8"
[compileJava, compileTestGroovy, compileTestJava]*.options*.compilerArgs = [
        '-Xlint:all,-options,-processing,-path'
        , '-Xep:RemoveUnusedImports:WARN'
        , '-Xep:InsecureCryptoUsage:OFF'
        , '-Xep:ParameterName:OFF'
]
  • [compileJava, compileTestGroovy, compileTestJava]*.options*.compilerArgs = [ ... ]compileJava.options.compilerArgs += [ ... ] に分けていたのを前者だけにまとめます。
  • '-Xep:ParameterName:OFF' を追加します。

警告:[deprecation] org.mockitoのMatchersは推奨されません

  • import static org.mockito.Matchers.any;Matchers が非推奨になっていたので、import 文を削除した後 Alt+Enter を押して import し直します。

警告:[deprecation] FilesのtoString(File,Charset)は推奨されません

f:id:ksby:20180905010116p:plain

Guava の Files#toString が非推奨になっていました。最近 Guava は使用しなくなる傾向にあるので(Spring Boot の BOM にも入っていません)、Spring Framework に入っている FileCopyUtils#copyToString に置き換えることにします。

例えば Files.toString(new File("src/test/resources/ksbysample/webapp/lending/helper/mail/assertdata/001/message.txt"), Charsets.UTF_8) は以下のように変更します。

  • フィールドに @Value("ksbysample/webapp/lending/helper/mail/assertdata/001/message.txt") ClassPathResource messageTxtResource; を追加する。
  • FileCopyUtils.copyToString(Files.newReader(messageTxtResource.getFile(), StandardCharsets.UTF_8))); に変更する。

f:id:ksby:20180905065522p:plain

修正したのは以下のソースです。

  • src/test/java/ksbysample/webapp/lending/helper/mail/Mail001HelperTest.java
  • src/test/java/ksbysample/webapp/lending/helper/mail/Mail002HelperTest.java
  • src/test/java/ksbysample/webapp/lending/helper/mail/Mail003HelperTest.java
  • src/test/java/ksbysample/webapp/lending/listener/rabbitmq/InquiringStatusOfBookQueueListenerTest.java
  • src/test/java/ksbysample/webapp/lending/web/confirmresult/ConfirmresultControllerTest.java
  • src/test/java/ksbysample/webapp/lending/web/lendingapp/LendingappControllerTest.java
  • src/test/java/ksbysample/webapp/lending/web/lendingapproval/LendingapprovalControllerTest.java

警告:[deprecation] MockMvcRequestBuildersのfileUpload(String,Object...)は推奨されません

f:id:ksby:20180905211554p:plain

MockMvcRequestBuilders#fileUpload が非推奨になっていたので、MockMvcRequestBuilders#multipart に置き換えます。修正したのは以下のソースです。

  • src/test/java/ksbysample/webapp/lending/web/booklist/BooklistControllerTest.java

次回は。。。

ここまでの変更ではまだ BUILD SUCCESSFUL は出ておらず、以下の問題が残っています。

  • 警告:[deprecation] org.springframework.web.servlet.mvc.method.annotationのAbstractJsonpResponseBodyAdviceは推奨されません が出ている。
  • FindBugs rule violations were found. See the report at: file:///D:/project-springboot/ksbysample-webapp-lending/build/reports/findbugs/main.html が出ている。
  • テストが4件失敗している。

f:id:ksby:20180905213339p:plain f:id:ksby:20180905213506p:plain

次回は AbstractJsonpResponseBodyAdvice の警告と、失敗しているテストを解消します。

履歴

2018/09/05
初版発行。