かんがるーさんの日記

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

Spring Boot 2.2.x の Web アプリを 2.3.x へバージョンアップする ( 感想 )

記事一覧はこちらです。

8月に完了させるつもりでしたが、Docker image のバージョンアップがうまく出来ず 12月までかかってしまいました。。。 Spring Boot はもう 2.4.1 までリリースされているにもかかわらず。Spring Boot のバージョンアップは Spring Boot 自体は Release Notes を見ればほとんど問題はないのですが、使用しているモジュールやツールのバージョンアップの方が大変なのかもしれません。

  • 今回も大きな変更はなく、Spring Boot のバージョンアップ自体は Spring Boot 2.3 Release Notes を見れば容易に出来ました。このバージョンから Kubernetes 向けの機能が少しずつ入ってきている印象です。

  • Checkstyle はこれまで google_checks.xml をベースに一部修正して使っていましたが、Java 14 向けの定義も入ってきて Java 11 で開発していると削除しないといけない箇所が出てきて少し分かりにくくなりました。

  • SpotBugs は beta が取れて設定もすっきりして使いやすくなりました。

  • 今回一番苦労したのが Docker image のバージョンアップでした。

    • pgAdmin 4 でログインができなくなり、ソースを確認しないと原因が分かりませんでした。
    • Redis は 5 → 6 へのメジャーバージョンアップでしたが、大きな機能追加が行われているわりにはバージョン番号を上げるだけで大丈夫でした。
    • 一番苦労したのが RabbitMQ です。メジャーバージョンアップでもマイナーバージョンアップでもないのに。。。 環境変数 RABBITMQ_ERLANG_COOKIE の使用が deprecated になったので .erlang.cookie file に変えようとしましたが、RabbitMQ が permission をチェックしていて、かつ Docker image で .erlang.cookie を配置するディレクトリを VOLUME コマンドで指定されている場合に permission を変更する方法が全然分かりませんでした。
    • Grafana もメジャーバージョンアップでしたが、こちらもバージョン番号を上げるだけで済みました。
  • Doma 2 が結構大きく変わりました。これまでそんな大きな変更は入らないモジュールという印象でしたが、今回見た限りでも以下の点が追加・変更されています。

    • build.gradle の記述の仕方が変わりました。
    • ログの出力で SLF4J がサポートされました。
    • Doma-Gen がなくなって doma-codegen-plugin に変わりました。
    • Criteria API が追加されました。
  • Build OCI images with Cloud Native Buildpacks が便利ですね。Docker image の生成はこれで十分という印象です。Web アプリをコンテナで運用することが増えたので、今回のバージョンアップはこれが一番うれしい機能追加なのかもしれません。

次は 2.4 へのバージョンアップかな、と思いつつ別のことを書くかもしれません。あと来年は JDK 17、Gradle 7、Spock 2.0(Groovy も 3系へ)あたりのバージョンアップがあるのか。。。

Spring Boot 2.2.x の Web アプリを 2.3.x へバージョンアップする ( その19 )( Docker で複数の Tomcat を起動して動作確認する )

概要

記事一覧はこちらです。

Spring Boot 2.2.x の Web アプリを 2.3.x へバージョンアップする ( その18 )( Build OCI images with Cloud Native Buildpacks を試してみる ) の続きです。

  • 今回の手順で確認できるのは以下の内容です。
    • Build OCI images with Cloud Native Buildpacks の機能で作成した Docker image で Web アプリを実行して動作確認します。
    • 今回はいろいろ苦労したので、動作確認時の手順を docker-compose up -d から一通り書いてみます。

参照したサイト・書籍

目次

  1. docker-compose up -d を実行する
  2. clean タスク実行 → Rebuild Project 実行 → build タスクを実行する
  3. bootBuildImage タスクを実行する
  4. Docker で複数の Tomcat を起動して動作確認する

手順

docker-compose up -d を実行する

docker-compose up -d を実行します。

f:id:ksby:20201230085246p:plain

rabbitmq-create-user コンテナに以下の画像の赤枠の Adding user "rabbitmq" ... 等のメッセージが出力されることを確認します。これまで何度も実行しましたが、たまに失敗することがありました。

f:id:ksby:20201230085401p:plain

http://localhost:1936/haproxy?stats にアクセスして全て緑になっていることを確認します。

f:id:ksby:20201230085629p:plain

clean タスク実行 → Rebuild Project 実行 → build タスクを実行する

clean タスク実行 → Rebuild Project 実行 → build タスクを実行して BUILD SUCCESSFUL のメッセージが出力されることを確認します。

f:id:ksby:20201230090319p:plain

bootBuildImage タスクを実行する

bootBuildImage タスクを実行して Successfully built image 'docker.io/library/ksbysample-webapp-lending:2.3.7-RELEASE'BUILD SUCCESSFUL のメッセージが出力されることを確認します。

f:id:ksby:20201230090801p:plain

Docker で複数の Tomcat を起動して動作確認する

docker-compose.app.yml で「bootBuildImage で生成した docker image を利用する場合の設定」の方の app コンテナの設定が有効になっていることを確認してから、

services:
#  # docker/app/Dockerfile で生成した docker image を利用する場合の設定
#  app:
#    build:
#      context: .
#      dockerfile: docker/app/Dockerfile
#    image: ksbysample-webapp-lending
#    volumes:
#      - ./build/libs/ksbysample-webapp-lending-2.3.7-RELEASE.jar:/app.jar
#      - ./docker/app/docker-entrypoint.sh:/usr/local/bin/docker-entrypoint.sh
#    environment:
#      - SPRING_DATASOURCE_HIKARI_JDBC_URL=jdbc:postgresql://postgresql/ksbylending
#      - SPRING_MAIL_HOST=mail-server
#      - SPRING_RABBITMQ_HOST=haproxy
#    deploy:
#      mode: replicated
#      replicas: 3
#    # entrypoint: /bin/sh
#    # stdin_open: true
#    # tty: true

  # bootBuildImage で生成した docker image を利用する場合の設定
  # docker exec -it ksbysample-webapp-lending_app_1 /bin/bash
  app:
    image: ksbysample-webapp-lending:2.3.7-RELEASE
    environment:
      - JAVA_TOOL_OPTIONS=-Dspring.profiles.active=product -Dlogging.appender=CONSOLE
      - SPRING_DATASOURCE_HIKARI_JDBC_URL=jdbc:postgresql://postgresql/ksbylending
      - SPRING_MAIL_HOST=mail-server
      - SPRING_RABBITMQ_HOST=haproxy
    deploy:
      mode: replicated
      replicas: 3
    # entrypoint: /bin/bash
    # stdin_open: true
    # tty: true

..........

以下のコマンドを実行してメールサーバ、Web アプリを起動します。

  • docker-compose -f docker-compose.mail.yml up -d
  • docker-compose -f docker-compose.app.yml --compatibility up -d

f:id:ksby:20201230090518p:plain f:id:ksby:20201230091031p:plain

app コンテナの1つのログを見て Started Application in ... seconds のログが出力されることを確認します。

f:id:ksby:20201230091207p:plain

http://localhost:8080/haproxy?stats にアクセスして全て緑になっていることを確認します。

f:id:ksby:20201230091347p:plain

以下の手順で動作確認します ( 画面キャプチャは省略します )。

  • ブラウザを起動して http://localhost:8080/ にアクセスしてログイン画面を表示します。tanaka.taro@sample.com / taro でログインします。
  • 検索対象図書館登録画面が表示されます。"東京都" で検索した後、一覧表示されている図書館から「国立国会図書館東京本館」を選択します。
  • ログアウトします。
  • ログイン画面に戻るので suzuki.hanako@test.co.jp / hanako でログインします。
  • 貸出希望書籍 CSV ファイルアップロード画面が表示されます。以下の内容が記述された CSV ファイルをアップロードします。

    "ISBN","書名"
    "978-4-7741-6366-6","GitHub実践入門"
    "978-4-7741-5377-3","JUnit実践入門"
    "978-4-7973-8014-9","Java最強リファレンス"
    "978-4-7973-4778-4","アジャイルソフトウェア開発の奥義"
    "978-4-87311-704-1","Javaによる関数型プログラミング"

  • 「貸出状況を確認しました」のメールが送信されるので、メールに記述されている URL にアクセスします。
  • 貸出申請画面が表示されます。3冊程「申請する」を選択して申請します。
  • ログアウトします。
  • 「貸出申請がありました」のメールが送信されるので、メールに記述されている URL にアクセスします。ログイン画面が表示されるので、tanaka.taro@sample.com / taro でログインします。
  • 貸出承認画面が表示されます。「承認」あるいは「却下」を選択して確定させます。
  • ログアウトします。
  • 「貸出申請が承認・却下されました」のメールが送信されるので、メールに記述されている URL にアクセスします。ログイン画面が表示されるので、suzuki.hanako@test.co.jp / hanako でログインします。
  • 貸出申請結果確認画面が表示されるので内容を確認します。

動作確認は特に問題ありませんでした。

以下のコマンドを実行してコンテナを停止します。

  • docker-compose -f docker-compose.app.yml --compatibility down
  • docker-compose -f docker-compose.mail.yml down
  • docker-compose down

履歴

2020/12/30
初版発行。

Spring Boot 2.2.x の Web アプリを 2.3.x へバージョンアップする ( その18 )( Build OCI images with Cloud Native Buildpacks を試してみる )

概要

記事一覧はこちらです。

Spring Boot 2.2.x の Web アプリを 2.3.x へバージョンアップする ( その17 )( app コンテナを実行する Alpine Linux で ja_JP.utf8 のロケールを使えるようにする ) の続きです。

  • 今回の手順で確認できるのは以下の内容です。
    • Build OCI images with Cloud Native Buildpacks に記載されていますが、2.3 から Cloud Native Buildpacks を使って Docker image を生成する機能が追加されました。この機能を利用して Docker image を生成し、Web アプリを動かしてみます。

参照したサイト・書籍

  1. Build OCI images with Cloud Native Buildpacks
    https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-2.3-Release-Notes#build-oci-images-with-cloud-native-buildpacks

  2. 31.Building Container Images
    https://docs.spring.io/spring-boot/docs/2.3.7.RELEASE/reference/html/spring-boot-features.html#boot-features-container-images

  3. 5.Packaging OCI Images
    https://docs.spring.io/spring-boot/docs/2.3.7.RELEASE/gradle-plugin/reference/html/#build-image

  4. Cloud Native Buildpacks
    https://buildpacks.io/

  5. paketo - Java Buildpack
    https://paketo.io/docs/buildpacks/language-family-buildpacks/java/

  6. Buildpacksのビルダーをスクラッチから作ってみる
    https://future-architect.github.io/articles/20201002/

  7. Creating Optimized Docker Images for a Spring Boot Application
    https://reflectoring.io/spring-boot-docker/

目次

  1. bootBuildImage タスクで Docker image を生成する
  2. 生成した Docker image で app コンテナを起動する
  3. messages_ja_JP.properties → messages_ja.properties にリネームして日本語のメッセージが表示されるようにする
  4. 最後に

手順

bootBuildImage タスクで Docker image を生成する

Gradle Tool Window を見ると bootBuildImage タスクがありますので実行します。

f:id:ksby:20201228231313p:plain

Successfully built image 'docker.io/library/ksbysample-webapp-lending:2.3.7-RELEASE'BUILD SUCCESSFUL のメッセージが出力されて Docker image の生成に成功しました。

f:id:ksby:20201228231602p:plain

右側には以下のログが出力されていました。

23:13:27: Executing task 'bootBuildImage'...

> Task :bootBuildInfo
> Task :copyDomaResources UP-TO-DATE
> Task :compileJava UP-TO-DATE
> Task :compileGroovy NO-SOURCE
> Task :generateGitProperties
> Task :processResources
> Task :classes
> Task :bootJar

> Task :bootBuildImage
Building image 'docker.io/library/ksbysample-webapp-lending:2.3.7-RELEASE'

 > Pulling builder image 'gcr.io/paketo-buildpacks/builder:base-platform-api-0.3' ..................................................
 > Pulled builder image 'gcr.io/paketo-buildpacks/builder@sha256:88d93729c291dfdf320fa21a8f8ae2c1d7366f9e602f4eab6ed88cec653f9d7d'
 > Pulling run image 'docker.io/paketobuildpacks/run:base-cnb' ..................................................
 > Pulled run image 'paketobuildpacks/run@sha256:f393fa2927a2619a10fc09bb109f822d20df909c10fed4ce3c36fad313ea18e3'
 > Executing lifecycle version v0.10.1
 > Using build cache volume 'pack-cache-50ed1ff0b3a5.build'

 > Running creator
    [creator]     ===> DETECTING
    [creator]     5 of 18 buildpacks participating
    [creator]     paketo-buildpacks/ca-certificates   1.0.1
    [creator]     paketo-buildpacks/bellsoft-liberica 6.0.0
    [creator]     paketo-buildpacks/executable-jar    3.1.3
    [creator]     paketo-buildpacks/dist-zip          2.2.2
    [creator]     paketo-buildpacks/spring-boot       3.5.0
    [creator]     ===> ANALYZING
    [creator]     Restoring metadata for "paketo-buildpacks/ca-certificates:helper" from app image
    [creator]     Restoring metadata for "paketo-buildpacks/bellsoft-liberica:helper" from app image
    [creator]     Restoring metadata for "paketo-buildpacks/bellsoft-liberica:java-security-properties" from app image
    [creator]     Restoring metadata for "paketo-buildpacks/bellsoft-liberica:jre" from app image
    [creator]     Restoring metadata for "paketo-buildpacks/bellsoft-liberica:jvmkill" from app image
    [creator]     Restoring metadata for "paketo-buildpacks/executable-jar:class-path" from app image
    [creator]     Restoring metadata for "paketo-buildpacks/spring-boot:helper" from app image
    [creator]     Restoring metadata for "paketo-buildpacks/spring-boot:spring-cloud-bindings" from app image
    [creator]     Restoring metadata for "paketo-buildpacks/spring-boot:web-application-type" from app image
    [creator]     ===> RESTORING
    [creator]     ===> BUILDING
    [creator]     
    [creator]     Paketo CA Certificates Buildpack 1.0.1
    [creator]       https://github.com/paketo-buildpacks/ca-certificates
    [creator]       Launch Helper: Reusing cached layer
    [creator]     
    [creator]     Paketo BellSoft Liberica Buildpack 6.0.0
    [creator]       https://github.com/paketo-buildpacks/bellsoft-liberica
    [creator]       Build Configuration:
    [creator]         $BP_JVM_VERSION              11.*            the Java version
    [creator]       Launch Configuration:
    [creator]         $BPL_JVM_HEAD_ROOM           0               the headroom in memory calculation
    [creator]         $BPL_JVM_LOADED_CLASS_COUNT  35% of classes  the number of loaded classes in memory calculation
    [creator]         $BPL_JVM_THREAD_COUNT        250             the number of threads in memory calculation
    [creator]         $JAVA_TOOL_OPTIONS                           the JVM launch flags
    [creator]       BellSoft Liberica JRE 11.0.9: Reusing cached layer
    [creator]       Launch Helper: Reusing cached layer
    [creator]       JVMKill Agent 1.16.0: Reusing cached layer
    [creator]       Java Security Properties: Reusing cached layer
    [creator]     
    [creator]     Paketo Executable JAR Buildpack 3.1.3
    [creator]       https://github.com/paketo-buildpacks/executable-jar
    [creator]       Process types:
    [creator]         executable-jar: java org.springframework.boot.loader.JarLauncher
    [creator]         task:           java org.springframework.boot.loader.JarLauncher
    [creator]         web:            java org.springframework.boot.loader.JarLauncher
    [creator]     
    [creator]     Paketo Spring Boot Buildpack 3.5.0
    [creator]       https://github.com/paketo-buildpacks/spring-boot
    [creator]       Launch Helper: Reusing cached layer
    [creator]       Web Application Type: Contributing to layer
    [creator]         Servlet web application detected
    [creator]         Writing env.launch/BPL_JVM_THREAD_COUNT.default
    [creator]       Spring Cloud Bindings 1.7.0: Reusing cached layer
    [creator]       Image labels:
    [creator]         org.springframework.boot.spring-configuration-metadata.json
    [creator]         org.springframework.boot.version
    [creator]     ===> EXPORTING
    [creator]     Reusing layer 'paketo-buildpacks/ca-certificates:helper'
    [creator]     Reusing layer 'paketo-buildpacks/bellsoft-liberica:helper'
    [creator]     Reusing layer 'paketo-buildpacks/bellsoft-liberica:java-security-properties'
    [creator]     Reusing layer 'paketo-buildpacks/bellsoft-liberica:jre'
    [creator]     Reusing layer 'paketo-buildpacks/bellsoft-liberica:jvmkill'
    [creator]     Reusing layer 'paketo-buildpacks/executable-jar:class-path'
    [creator]     Reusing layer 'paketo-buildpacks/spring-boot:helper'
    [creator]     Reusing layer 'paketo-buildpacks/spring-boot:spring-cloud-bindings'
    [creator]     Reusing layer 'paketo-buildpacks/spring-boot:web-application-type'
    [creator]     Adding 1/1 app layer(s)
    [creator]     Reusing layer 'launcher'
    [creator]     Reusing layer 'config'
    [creator]     Adding label 'io.buildpacks.lifecycle.metadata'
    [creator]     Adding label 'io.buildpacks.build.metadata'
    [creator]     Adding label 'io.buildpacks.project.metadata'
    [creator]     Adding label 'org.springframework.boot.spring-configuration-metadata.json'
    [creator]     Adding label 'org.springframework.boot.version'
    [creator]     *** Images (7904578079ee):
    [creator]           docker.io/library/ksbysample-webapp-lending:2.3.7-RELEASE

Successfully built image 'docker.io/library/ksbysample-webapp-lending:2.3.7-RELEASE'


Deprecated Gradle features were used in this build, making it incompatible with Gradle 7.0.
Use '--warning-mode all' to show the individual deprecation warnings.
See https://docs.gradle.org/6.5.1/userguide/command_line_interface.html#sec:command_line_warnings

BUILD SUCCESSFUL in 19s
7 actionable tasks: 5 executed, 2 up-to-date
23:13:46: Task execution finished 'bootBuildImage'.

IntelliJ IDEA で Docker image を見ると ksbysample-webapp-lending:2.3.7-RELEASE が生成されていることが確認できました。Size が 328.2MB と結構大きいです。あと Created が 41 years ago でした。。。なぜ?(bootBuildImage タスクを実行すると 41年後に飛ばされることを知ったのはこの少し後でした。今私は未来から bootBuildImage タスクを実行してはいけないことを警告するためにこのブログを書いていますwww)

理由を調べたら Spring Boot 2.3.0 buildpack builds image with creation date 40 years ago を見つけました。

f:id:ksby:20201228232001p:plain

生成した Docker image で app コンテナを起動する

docker-compose.app.yml を以下のように変更します。

services:
#  # docker/app/Dockerfile で生成した docker image を利用する場合の設定
#  app:
#    build:
#      context: .
#      dockerfile: docker/app/Dockerfile
#    image: ksbysample-webapp-lending
#    volumes:
#      - ./build/libs/ksbysample-webapp-lending-2.3.7-RELEASE.jar:/app.jar
#      - ./docker/app/docker-entrypoint.sh:/usr/local/bin/docker-entrypoint.sh
#    environment:
#      - SPRING_DATASOURCE_HIKARI_JDBC_URL=jdbc:postgresql://postgresql/ksbylending
#      - SPRING_MAIL_HOST=mail-server
#      - SPRING_RABBITMQ_HOST=haproxy
#    deploy:
#      mode: replicated
#      replicas: 3
#    # entrypoint: /bin/sh
#    # stdin_open: true
#    # tty: true

  # bootBuildImage で生成した docker image を利用する場合の設定
  # docker exec -it ksbysample-webapp-lending_app_1 /bin/bash
  app:
    image: ksbysample-webapp-lending:2.3.7-RELEASE
    environment:
      - JAVA_TOOL_OPTIONS=-Dspring.profiles.active=product -Dlogging.appender=CONSOLE
      - SPRING_DATASOURCE_HIKARI_JDBC_URL=jdbc:postgresql://postgresql/ksbylending
      - SPRING_MAIL_HOST=mail-server
      - SPRING_RABBITMQ_HOST=haproxy
    deploy:
      mode: replicated
      replicas: 3
    # entrypoint: /bin/bash
    # stdin_open: true
    # tty: true

..........
  • 以前の app コンテナの設定は全てコメントアウトし、新しい app コンテナの設定を追加します。
  • Docker image が ksbysample-webapp-lending:2.3.7-RELEASE で生成されているので、image にこれを記述します。
  • environment には以前の app コンテナに指定していたものを全てコピーした後、docker/app/docker-entrypoint.sh で指定していた JVM の起動時オプションのうち -Dspring.profiles.active=product -Dlogging.appender=CONSOLE の2つを指定したいので、Runtime JVM Configuration を参考に JAVA_TOOL_OPTIONS=-Dspring.profiles.active=product -Dlogging.appender=CONSOLE を追加します。

docker-compose -f docker-compose.app.yml --compatibility up -d コマンドで app コンテナを起動します。

f:id:ksby:20201229152643p:plain

Spring Boot のロゴの前に出力されているログは以下の内容でした。

Setting Active Processor Count to 2
Calculating JVM memory based on 2722764K available memory
Calculated JVM Memory Configuration: -XX:MaxDirectMemorySize=10M -Xmx2066762K -XX:MaxMetaspaceSize=144001K -XX:ReservedCodeCacheSize=240M -Xss1M (Total Memory: 2722764K, Thread Count: 250, Loaded Class Count: 23010, Headroom: 0%)
Adding 138 container CA certificates to JVM truststore
Spring Cloud Bindings Enabled
Picked up JAVA_TOOL_OPTIONS: -Dspring.profiles.active=product -Dlogging.appender=CONSOLE -Djava.security.properties=/layers/paketo-buildpacks_bellsoft-liberica/java-security-properties/java-security.properties -agentpath:/layers/paketo-buildpacks_bellsoft-liberica/jvmkill/jvmkill-1.16.0-RELEASE.so=printHeapHistogram=1 -XX:ActiveProcessorCount=2 -XX:MaxDirectMemorySize=10M -Xmx2066762K -XX:MaxMetaspaceSize=144001K -XX:ReservedCodeCacheSize=240M -Xss1M -Dorg.springframework.cloud.bindings.boot.enable=true

http://localhost:8080/ にアクセスするとログイン画面が表示されてログインして機能も一通り動いたのですが、ログイン画面で何も入力せずに「ログイン」ボタンをクリックしたら日本語のメッセージが表示されませんでした。

f:id:ksby:20201229153231p:plain

messages_ja_JP.properties → messages_ja.properties にリネームして日本語のメッセージが表示されるようにする

docker exec -it ksbysample-webapp-lending_app_1 /bin/bash コマンドで起動した app コンテナの1つに接続して locate -a コマンドを実行してみましたが、locate: command not found のメッセージが出力されました。locale コマンドはインストールされていないようです。

f:id:ksby:20201229154319p:plain

locale を設定する方法を Web で調べてみましたが、それらしい情報がヒットしません。

docker-compose.app.yml で環境変数 LANG、LC_ALL に ja_JP.UTF-8 を設定してみても、

  app:
    image: ksbysample-webapp-lending:2.3.7-RELEASE
    environment:
      - JAVA_TOOL_OPTIONS=-Dspring.profiles.active=product -Dlogging.appender=CONSOLE
      - SPRING_DATASOURCE_HIKARI_JDBC_URL=jdbc:postgresql://postgresql/ksbylending
      - SPRING_MAIL_HOST=mail-server
      - SPRING_RABBITMQ_HOST=haproxy
      - LANG=ja_JP.UTF-8
      - LC_ALL=ja_JP.UTF-8
    deploy:
      mode: replicated
      replicas: 3

bash: warning: setlocale: LC_ALL: cannot change locale (ja_JP.utf8) のメッセージが出力されて設定できませんでした。

f:id:ksby:20201229162630p:plain

どう対応してよいのか良く分からなくなったのですが、メッセージを見直してみると ... for locale 'ja'. と出力されており、もしかして ja_JP ではなく ja?と思ってファイル名を messages_ja_JP.properties → messages_ja.properties に変更してみたところ日本語のメッセージが表示されるようになりました。

f:id:ksby:20201229163821p:plain

docker/app/Dockerfile で build した Docker image で Web アプリを起動しても、docker/app/Dockerfile を glibc をインストールしないバージョンに戻してから Docker image を作り直して Web アプリを起動しても、WindowsIntelliJ IDEA から Web アプリを起動しても、日本語のメッセージが表示されました。そうか、これで良かったのか。。。

最後に

bootBuildImage タスクを実行するだけで Docker image が簡単に作れます。Spring Boot、ますます便利になった印象です。

履歴

2020/12/29
初版発行。

Spring Boot 2.2.x の Web アプリを 2.3.x へバージョンアップする ( その17 )( app コンテナを実行する Alpine Linux で ja_JP.utf8 のロケールを使えるようにする )

概要

記事一覧はこちらです。

Spring Boot 2.2.x の Web アプリを 2.3.x へバージョンアップする ( その16 )( ValuesHelper クラスで guava の ClassPath を使用しないよう変更する ) の続きです。

  • 今回の手順で確認できるのは以下の内容です。
    • Alpine Linux ベースの app コンテナで Web アプリを実行すると日本語のメッセージが表示されないことに気づいたので、その問題を解消します。

参照したサイト・書籍

  1. Dockerコンテナ上でJavaプログラムを動かすときにLANG環境変数を設定すると日本語のファイル名が文字化けする問題
    https://qiita.com/Targityen/items/f921c95e684810d7087f

  2. alpineベースのDockerイメージだとlocaledefが動かない
    https://hacknote.jp/archives/26886/

  3. teikoku-penguin / alpine-ja_JP/ Dockerfile
    https://github.com/teikoku-penguin/alpine-ja_JP/blob/master/Dockerfile

  4. sgerrand / alpine-pkg-glibc
    https://github.com/sgerrand/alpine-pkg-glibc

  5. AdoptOpenJDK / openjdk-docker
    https://github.com/AdoptOpenJDK/openjdk-docker

  6. How to set locale in Docker Alpine?
    https://stackoverflow.com/questions/49042223/how-to-set-locale-in-docker-alpine

  7. ロケール環境変数」の種類と優先順位まとめ【LC_ALL・LC_*・LANG・LANGUAGE】
    https://linuxfan.info/locale-variables

目次

  1. Docker で Web アプリを実行すると日本語のメッセージが表示されない
  2. app コンテナの Alpine Linux に sgerrand/alpine-pkg-glibc をインストールして ja_JP.utf8 を使用可能にする

手順

Docker で Web アプリを実行すると日本語のメッセージが表示されない

動作確認をしていて気づいたのですが、IntelliJ IDEA から Web アプリを実行した時にはログイン画面から何も入力せずに「ログイン」ボタンを押すと日本語のメッセージが表示されますが、

f:id:ksby:20201228163523p:plain

Docker 上で adoptopenjdk/openjdk11:jdk-11.0.9.1_1-alpine-slim ベースのコンテナから Web アプリを実行した時には日本語のメッセージが表示されません。

f:id:ksby:20201228163929p:plain

Dockerコンテナ上でJavaプログラムを動かすときにLANG環境変数を設定すると日本語のファイル名が文字化けする問題 の記事によると日本語ロケールが登録されていないためらしいのですが、docker/app/docker-entrypoint.sh に locale -a を追加して実行しても、

#!/bin/sh
# 改行コードを LF にすること。LF でないと実行されない。

export JAVA_OPTS="-Xms1024m -Xmx1024m -XX:MaxMetaspaceSize=384m"

locale -a
exec java $JAVA_OPTS \
          -Djava.security.egd=file:/dev/./urandom \
          -Dspring.profiles.active=product \
          -Dserver.tomcat.basedir=/ \
          -Dlogging.appender=CONSOLE \
          -jar /app.jar

locale: not found のメッセージが表示されて、指定可能なロケールを確認することが出来ませんでした。

f:id:ksby:20201228164455p:plain

app コンテナの Alpine Linux に sgerrand/alpine-pkg-glibc をインストールして ja_JP.utf8 を使用可能にする

alpineベースのDockerイメージだとlocaledefが動かない の記事によると glibc 関連らしく、もう少し調べていたら teikoku-penguin/alpine-ja_JP/Dockerfile を見つけました。

docker/app/Dockerfile を以下のように変更します。

FROM adoptopenjdk/openjdk11:jdk-11.0.9.1_1-alpine-slim

RUN apk update && \
    apk upgrade; \
    wget -q -O /etc/apk/keys/sgerrand.rsa.pub https://alpine-pkgs.sgerrand.com/sgerrand.rsa.pub; \
    wget https://github.com/sgerrand/alpine-pkg-glibc/releases/download/2.31-r0/glibc-2.31-r0.apk; \
    wget https://github.com/sgerrand/alpine-pkg-glibc/releases/download/2.31-r0/glibc-bin-2.31-r0.apk; \
    wget https://github.com/sgerrand/alpine-pkg-glibc/releases/download/2.31-r0/glibc-i18n-2.31-r0.apk; \
    apk add --no-cache --update \
    bash \
    tzdata \
    glibc-2.31-r0.apk \
    glibc-bin-2.31-r0.apk \
    glibc-i18n-2.31-r0.apk; \
    rm glibc-2.31-r0.apk glibc-bin-2.31-r0.apk glibc-i18n-2.31-r0.apk

RUN /usr/glibc-compat/bin/localedef -i ja_JP -f UTF-8 ja_JP.UTF-8

ENV TZ Asia/Tokyo
ENV LANG ja_JP.utf8
ENV LC_ALL ja_JP.utf8

VOLUME /tmp
EXPOSE 8080
ENTRYPOINT ["docker-entrypoint.sh"]
  • RUN apk add --no-cache tzdataRUN apk update && ... rm glibc-2.31-r0.apk glibc-bin-2.31-r0.apk glibc-i18n-2.31-r0.apk に変更します。openjdk-docker/11/jdk/alpine/Dockerfile.hotspot.releases.slim を見ると glibc のバージョンが 2.31-r0 でしたので apk update ... のコマンド内で指定する glibc のバージョンを 2.31-r0 に変更します。
  • この方法でインストールした後 locale -a コマンドを実行して表示されたロケールja_JP.utf8 でしたので、ENV LANG="ja_JP.UTF-8"ENV LANG ja_JP.utf8 に変更します。
  • 環境変数 LANG を指定しただけでは日本語メッセージが表示されない問題が解消されないため ENV LC_ALL ja_JP.utf8 を追加します。

docker/app/docker-entrypoint.sh にロケール一覧を確認するために /usr/glibc-compat/bin/locale -a を追加します。

#!/bin/sh
# 改行コードを LF にすること。LF でないと実行されない。

export JAVA_OPTS="-Xms1024m -Xmx1024m -XX:MaxMetaspaceSize=384m"

/usr/glibc-compat/bin/locale -a
exec java $JAVA_OPTS \
          -Djava.security.egd=file:/dev/./urandom \
          -Dspring.profiles.active=product \
          -Dserver.tomcat.basedir=/ \
          -Dlogging.appender=CONSOLE \
          -jar /app.jar

docker-compose -f docker-compose.app.yml --compatibility build --no-cache コマンドを実行して Docker Image を作り直します。

f:id:ksby:20201228171500p:plain f:id:ksby:20201228171641p:plain f:id:ksby:20201228171738p:plain

docker-compose -f docker-compose.app.yml --compatibility up -d コマンドで app コンテナを実行します。/usr/glibc-compat/bin/locale -a コマンドが実行されると ja_JP.utf8 が表示されます。

f:id:ksby:20201228172510p:plain

ログイン画面から何も入力せずに「ログイン」ボタンを押すと日本語のメッセージが表示されました。

f:id:ksby:20201228172725p:plain

履歴

2020/12/28
初版発行。

Spring Boot 2.2.x の Web アプリを 2.3.x へバージョンアップする ( 番外編 )( IntelliJ IDEA の docToolchain/diagrams.net-intellij-plugin を追加する )

概要

記事一覧はこちらです。

Twitter で draw.io を直接利用できる IntelliJ IDEA の Plugin がリリースされたと見かけました。 まだ This plugin is still an early version and experimental. とのことですが、欲しいと思っていた Plugin なのでインストールしてみます。

参照したサイト・書籍

  1. docToolchain / diagrams.net-intellij-plugin
    https://github.com/docToolchain/diagrams.net-intellij-plugin

  2. Draw.io Integration for IntelliJ
    https://drawio-intellij-plugin.netlify.app/

目次

  1. docToolchain/diagrams.net-intellij-plugin を追加する

手順

docToolchain/diagrams.net-intellij-plugin を追加する

IntelliJ IDEA の Plugin の画面から diagrams.net-intellij-plugin で検索してインストールします。

f:id:ksby:20201226222041p:plain

.sample/sample.drawio を作成して開くと VS Code の Extension と同じように draw.io の画面が表示されます。

f:id:ksby:20201226230430p:plain

AWS のアイコンも使用でき、使い勝手も VS Code の Extension と変わらないようです。VS Code と違い IntelliJ IDEA らしく保存は自動で行われます。

f:id:ksby:20201226231132p:plain

.sample/sample.drawio を VS Code で開くと同じように表示されました。

f:id:ksby:20201226231443p:plain

Import/Export や Save の機能はまだでした(左が IntelliJ IDEA、右が VS Code)。

f:id:ksby:20201226231709p:plainf:id:ksby:20201226231806p:plain

未実装の機能がありますが、結構良さそうです。使っていきたいと思います。

またどうやって作るのかソースを見たところ、Kotlin で書かれていました。テストは Groovy で Spock でしたが。そうか、そういう組み合わせもあるのか。

履歴

2020/12/26
初版発行。

Spring Boot 2.2.x の Web アプリを 2.3.x へバージョンアップする ( その16 )( ValuesHelper クラスで guava の ClassPath を使用しないよう変更する )

概要

記事一覧はこちらです。

Spring Boot 2.2.x の Web アプリを 2.3.x へバージョンアップする ( その15 )( Doma 2 を 2.26.0 → 2.44.3 へバージョンアップする+domaGen タスクを doma-codegen-plugin を利用したものに作り直す ) の続きです。

  • 今回の手順で確認できるのは以下の内容です。
    • ksbysample.webapp.lending.values.ValuesHelper クラスのコンストラクタで values パッケージの下のクラス一覧を取得してフィールドの Map オブジェクトに保存しており、現在 guava の ClassPath クラスを利用しています。
    • Spring のクラスでも実現できるのではないかと思い以前から変更方法を調べていたのですが、その方法を見つけたので変更します。Web アプリの中で com.google.common.collect.Multiset を使用している箇所があるので guava を依存関係から削除することはできませんが、values パッケージを利用するだけなら guava を依存関係に追加する必要がなくります。

参照したサイト・書籍

目次

  1. ksbysample.webapp.lending.values.ValuesHelper クラスで guava の ClassPath を使用しないよう変更する

手順

ksbysample.webapp.lending.values.ValuesHelper クラスで guava の ClassPath を使用しないよう変更する

現在 guava の ClassPath を使用して以下のように実装していますが、

import com.google.common.reflect.ClassPath;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * ???
 */
@Component("vh")
public final class ValuesHelper {

    private final Map<String, String> valuesObjList;

    private ValuesHelper(@Value("${valueshelper.classpath.prefix:}") String classpathPrefix) throws IOException {
        ClassLoader loader = Thread.currentThread().getContextClassLoader();
        valuesObjList = ClassPath.from(loader)
                .getTopLevelClassesRecursive(classpathPrefix + this.getClass().getPackage().getName())
                .stream()
                .filter(classInfo -> {
                    try {
                        Class<?> clazz = Class.forName(classInfo.getName().replace(classpathPrefix, ""));
                        return !clazz.equals(Values.class) && Values.class.isAssignableFrom(clazz);
                    } catch (ClassNotFoundException e) {
                        throw new RuntimeException(e);
                    }
                })
                .collect(Collectors.toMap(classInfo -> classInfo.getSimpleName()
                        , classInfo -> classInfo.getName().replace(classpathPrefix, "")));
    }

    ..........

Can you find all classes in a package using reflection? の 104 の Spring のコードを参考に以下のように変更します。@ComponentScan アノテーションがあるので Spring のクラスで実現できるはずと思っていましたが、ClassPathScanningCandidateComponentProvider クラスを使えばできることが分かりました。

import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
import org.springframework.core.type.filter.RegexPatternTypeFilter;
import org.springframework.stereotype.Component;

import java.util.Map;
import java.util.Set;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * ???
 */
@Component("vh")
public final class ValuesHelper {

    private final Map<String, String> valuesObjList;

    private ValuesHelper() {
        ClassPathScanningCandidateComponentProvider provider = new ClassPathScanningCandidateComponentProvider(false);
        provider.addIncludeFilter(new RegexPatternTypeFilter(Pattern.compile(".*")));
        Set<BeanDefinition> beans = provider.findCandidateComponents(this.getClass().getPackage().getName());
        valuesObjList = beans.stream()
                .map(bean -> {
                    try {
                        return Class.forName(bean.getBeanClassName());
                    } catch (ClassNotFoundException e) {
                        throw new RuntimeException(e);
                    }
                })
                .filter(clazz -> !clazz.equals(Values.class) && Values.class.isAssignableFrom(clazz))
                .collect(Collectors.toMap(clazz -> clazz.getSimpleName(), clazz -> clazz.getName()));
    }

    ..........

コンストラクタの引数に渡していた @Value("${valueshelper.classpath.prefix:}") String classpathPrefix を削除したので、以下の設定ファイルの項目を削除します。

  • src/main/resources/application.properties の valueshelper.classpath.prefix=
  • src/main/resources/application-product.properties の valueshelper.classpath.prefix=BOOT-INF.classes.

clean タスク実行 → Rebuild Project 実行 → build タスクを実行すると無事 "BUILD SUCCESSFUL" のメッセージが出力されました。

f:id:ksby:20201226195331p:plain

IntelliJ IDEA から Web アプリを起動しても Docker から Web アプリを起動しても動作には問題ありませんでした。

履歴

2020/12/26
初版発行。

Spring Boot 2.2.x の Web アプリを 2.3.x へバージョンアップする ( その15 )( Doma 2 を 2.26.0 → 2.44.3 へバージョンアップする+domaGen タスクを doma-codegen-plugin を利用したものに作り直す )

概要

記事一覧はこちらです。

その14 ( Docker コンテナの image をバージョンアップする、Spring Boot Statistics のデータが表示されていない Panel を修正する+Dashboard に JVM (Micrometer) を追加する ) の続きです。

参照したサイト・書籍

  1. Doma 2 - User Documentation - Building an application - Build with Gradle
    https://doma.readthedocs.io/en/latest/build/?highlight=org.seasar.doma%3Adoma#build-with-gradle

  2. domaframework / doma-codegen-plugin
    https://github.com/domaframework/doma-codegen-plugin

  3. Doma入門 - ログライブラリにSLF4Jを使う
    https://qiita.com/nakamura-to/items/0f8195c45eb3630a8daf

  4. domaframework / getting-started
    https://github.com/domaframework/getting-started

  5. Doma入門
    https://qiita.com/nakamura-to/items/deaff05ba530317f3cf8

目次

  1. Doma 2 を 2.26.0 → 2.44.3 へバージョンアップする
  2. domaGen タスクを doma-codegen-plugin を利用したものに作り直す
  3. clean タスク実行 → Rebuild Project 実行 → build タスクを実行する
  4. 警告:[MissingSummary] A summary line is required on public/protected Javadocs. の警告が出力されないようにする

手順

Doma 2 を 2.26.0 → 2.44.3 へバージョンアップする

https://doma.readthedocs.io/en/latest/build/?highlight=org.seasar.doma%3Adoma#build-with-gradle に従い build.gradle の以下の点を変更します。また Doma入門 - ログライブラリにSLF4Jを使うDoma 2 が SLF4J に対応したとの記事を読みました。org.seasar.doma:doma-slf4j を追加することにします。

..........

dependencies {
    def jdbcDriver = "org.postgresql:postgresql:42.2.14"
    def spockVersion = "1.3-groovy-2.5"
    def domaVersion = "2.44.3"
    def lombokVersion = "1.18.12"
    def errorproneVersion = "2.4.0"
    def powermockVersion = "2.0.7"
    def spotbugsVersion = "4.1.1"

    ..........

    // for Doma
    implementation("org.seasar.doma:doma-core:${domaVersion}")
    implementation("org.seasar.doma:doma-slf4j:${domaVersion}")
    annotationProcessor("org.seasar.doma:doma-processor:${domaVersion}")
    domaGenRuntime("org.seasar.doma:doma-gen:${domaVersion}")
    domaGenRuntime("${jdbcDriver}")
  • dependencies block の以下の点を変更します。
    • def domaVersion = "2.26.0"def domaVersion = "2.44.3" に変更します。
    • implementation("org.seasar.doma:doma:${domaVersion}")implementation("org.seasar.doma:doma-core:${domaVersion}") に変更します。
    • implementation("org.seasar.doma:doma-slf4j:${domaVersion}") を追加します。
    • annotationProcessor("org.seasar.doma:doma:${domaVersion}")annotationProcessor("org.seasar.doma:doma-processor:${domaVersion}") に変更します。

domaGen タスクを doma-codegen-plugin を利用したものに作り直す

build.gradle を以下のように変更します。

buildscript {
    ..........
    dependencies {
        // for doma-codegen-plugin
        classpath "org.postgresql:postgresql:42.2.14"
    }
}

plugins {
    ..........
    id "com.gorylenko.gradle-git-properties" version "2.2.3"
    id "org.seasar.doma.codegen" version "1.2.1"
}

..........

configurations {
    compileOnly.extendsFrom annotationProcessor

    // annotationProcessor と testAnnotationProcessor、compileOnly と testCompileOnly を併記不要にする
    testAnnotationProcessor.extendsFrom annotationProcessor
    testImplementation.extendsFrom compileOnly

    // for SpotBugs
    spotbugsStylesheets { transitive = false }
}

..........

// for doma-codegen-plugin
// まず変更が必要なもの
def rootPackageName = "ksbysample.webapp.lending"
def rootPackagePath = "src/main/java/ksbysample/webapp/lending"
def dbUrl = "jdbc:postgresql://localhost/ksbylending"
def dbUser = "ksbylending_user"
def dbPassword = "xxxxxxxx"
def dbTableNamePattern = ".*"
//def dbTableNamePattern = "user_info"
// おそらく変更不要なもの
def packageEntityPath = rootPackagePath + "/entity"
def packageDaoPath = rootPackagePath + "/dao"
def importOfComponentAndAutowiredDomaConfig = "${rootPackageName}.util.doma.ComponentAndAutowiredDomaConfig"
def workPath = "work"
def workEntityPath = "${workPath}/entity"
def workDaoPath = "${workPath}/dao"
task domaGen(group: "doma code generation") {
    // このタスク自体は何もしない。実行する時の起点用タスクとして作成している。
}
task beforeDomaCodeGen {
    doLast {
        // 作業用ディレクトリを削除する
        delete "${workPath}"

        // 現在の dao, entity パッケージのバックアップを取得する
        copy() {
            from "${packageDaoPath}"
            into "${workDaoPath}/org"
        }
        copy() {
            from "${packageEntityPath}"
            into "${workEntityPath}/org"
        }

        // dao, entity パッケージを削除する
        delete "${packageDaoPath}"
        delete "${packageEntityPath}"
    }
}
domaCodeGen {
    db {
        url = "${dbUrl}"
        user = "${dbUser}"
        password = "${dbPassword}"
        tableNamePattern = "${dbTableNamePattern}"
        ignoredTableNamePattern = "flyway_schema_history|SPRING_SESSION.*"
        entity {
            packageName = "${rootPackageName}.entity"
            useListener = false
            useMappedSuperclass = false
        }
        dao {
            packageName = "${rootPackageName}.dao"
        }
    }
}
task afterDomaCodeGen {
    doLast {
        // 生成された Entity クラスを作業用ディレクトリにコピーし、
        // @SuppressWarnings({"PMD.TooManyFields"}) アノテーションを付加する
        copy() {
            from "${packageEntityPath}"
            into "${workEntityPath}/replace"
            filter {
                line ->
                    line.replaceAll('@Entity', '@SuppressWarnings({"PMD.TooManyFields"})\n@Entity')
            }
        }

        // 生成された Dao インターフェースからバックアップにあるクラスを削除する
        // ※生成済の Dao インターフェースを再生成したい場合には事前に削除すること!
        for (workDaoFile in new File("${workDaoPath}/org").listFiles()) {
            def packageDaoFile = new File("${packageDaoPath}/${workDaoFile.name}")
            if (packageDaoFile.exists()) {
                packageDaoFile.delete()
            }
        }

        // 生成された Dao インターフェースを作業用ディレクトリにコピーし、
        // @ComponentAndAutowiredDomaConfig アノテーションを付加し、
        // Javadoc の @param に説明文を追加する
        copy() {
            from "${packageDaoPath}"
            into "${workDaoPath}/replace"
            filter {
                line ->
                    line.replaceAll('import org.seasar.doma.Dao;', "import ${importOfComponentAndAutowiredDomaConfig};\nimport org.seasar.doma.Dao;")
                            .replaceAll('@Dao', '@Dao\n@ComponentAndAutowiredDomaConfig')
                            .replaceAll('@param (\\S+)$', '@param $1 $1')
            }
        }

        // 元々 dao, entity パッケージ内にあったファイルを元に戻す
        copy() {
            from "${workDaoPath}/org"
            into "${packageDaoPath}"
        }
        copy() {
            from "${workEntityPath}/org"
            into "${packageEntityPath}"
        }

        // @ComponentAndAutowiredDomaConfig アノテーションを付加した Dao インターフェースを
        // dao パッケージへ戻す
        copy() {
            from "${workDaoPath}/replace"
            into "${packageDaoPath}"
        }

        // @SuppressWarnings({"PMD.TooManyFields"}) アノテーションを付加した Entity クラスを
        // entity パッケージへ戻す
        copy() {
            from "${workEntityPath}/replace"
            into "${packageEntityPath}"
        }

        // 作業用ディレクトリを削除する
        delete "${workPath}"
    }
}
// beforeDomaCodeGen --> domaCodeGenDbEntity --> domaCodeGenDbDao --> domaGen --> afterDomaCodeGen
domaCodeGenDbEntity.dependsOn beforeDomaCodeGen
domaCodeGenDbDao.dependsOn domaCodeGenDbEntity
domaGen.dependsOn domaCodeGenDbDao
domaGen.finalizedBy afterDomaCodeGen

..........
  • buildscript block に dependencies { classpath "org.postgresql:postgresql:42.2.14" } を追加します。
  • plugins block に id "org.seasar.doma.codegen" version "1.2.1" を追加します。
  • configurations block から domaGenRuntime を削除します。
  • dependencies block から以下の2行を削除します。
    • domaGenRuntime("org.seasar.doma:doma-gen:${domaVersion}")
    • domaGenRuntime("${jdbcDriver}")
  • // for doma-codegen-plugindomaGen.finalizedBy afterDomaCodeGen の部分を追加します。
    • 実現したい内容は以下の点でした。
      • Entity クラス、Dao インターフェースは doma-codegen-plugin で既存のテーブルから生成する。
      • 生成された Entity クラス には @SuppressWarnings({"PMD.TooManyFields"}) を追加する。
      • 生成された Dao インターフェースには @ComponentAndAutowiredDomaConfig とその import 文を追加する。
    • Spring Boot + npm + Geb で入力フォームを作ってテストする ( その91 )( Doma 2 を 2.28.0 → 2.34.0 へバージョンアップする+domaGen タスクを doma-codegen-plugin を利用したものに作り直す ) で1度変更版を作成しましたが、domaGen タスクを何度も実行すると Enttiy クラスの @SuppressWarnings({"PMD.TooManyFields"}) や Dao インターフェースの @ComponentAndAutowiredDomaConfig が何度も追加されるという問題があることに今回見直していて気づきました。
    • そこで以下のように修正しています。
      • Dao インターフェースだけでなく Entity クラスもバックアップを取得する。
      • doma-codegen-plugin のタスク実行前に dao、entity パッケージを丸ごと削除する(dbTableNamePattern 変数に設定したテーブルの Dao インターフェース、Entity クラスだけが dao、entity パッケージに作成されるようにする)。
      • 既に生成したことがある Dao インターフェースの再生成は禁止したいので、afterDomaCodeGen タスク内でバックアップに存在する Dao インターフェースは dao パッケージから削除する。

変更後、Gradle Tool Window の左上にある「Refresh all Gradle projects」ボタンをクリックして更新します。

今回改修した domaGen タスクでは dao、entity パッケージの下には何も変更が入っていない状態で、

f:id:ksby:20201223231110p:plain

domaGen タスクを実行しても、

f:id:ksby:20201223231239p:plain

dao、entity パッケージの下には何も変更はありません(色の付いたクラス、インターフェースがありません)。

f:id:ksby:20201223231336p:plain

user_info テーブルに test_column カラムを追加してから、

f:id:ksby:20201223231920p:plain

domaGen タスクを実行すると、

f:id:ksby:20201223232327p:plain

Dao インターフェースはそのままで UserInfo Entity クラスだけに変更が入ります。

f:id:ksby:20201223232814p:plain

clean タスク実行 → Rebuild Project 実行 → build タスクを実行する

clean タスク実行 → Rebuild Project 実行 → build タスクを実行すると "BUILD SUCCESSFUL" のメッセージは出力されたのですが、警告:[MissingSummary] A summary line is required on public/protected Javadocs. (see http://google.github.io/styleguide/javaguide.html#s7.2-summary-fragment) という警告メッセージも出力されました。compileJava タスクで出力されているので Error Prone が出力しているようです。

f:id:ksby:20201223234656p:plain

警告:[MissingSummary] A summary line is required on public/protected Javadocs. の警告が出力されないようにする

今回変更しているのは build.gradle と Entity クラス(上には記述していませんが domaGen タスクで作り直しています)で、http://google.github.io/styleguide/javaguide.html#s7.2-summary-fragment を見たところ、Entity クラスのクラスコメントが空だったことが原因でした。

f:id:ksby:20201223235314p:plain

??? を書いておくことにします。

再度 clean タスク実行 → Rebuild Project 実行 → build タスクを実行すると今度は警告メッセージは出力されませんでした。

f:id:ksby:20201224000205p:plain

履歴

2020/12/24
初版発行。