Spring Bootのロギング警告

## はじめに

こんにちは、[@rs_tukki](https://twitter.com/rs_tukki)です。
これは[ラクス Advent Calendar 2023](https://qiita.com/advent-calendar/2023/rakus)の22日目の記事です。

皆さん、Spring Bootは使われていますでしょうか。
JavaでWebアプリケーションを作るとなれば真っ先に候補に挙がるフレームワークですが、今回はそのSpring Bootのバージョンアップ作業中に遭遇した警告についての話をします。

## Spring Bootのバージョンアップ

Spring Bootは、2022年11月に3.0.0へのメジャーバージョンアップが行われてから既に1年が経過しています。  
3.0.0へのメジャーバージョンアップは破壊的変更も多く苦戦させられましたが、それ以降のバージョンアップでは大きな変更もなく、動作確認も順調に進んでいました。

そして2023年6月、3.1.1がリリースされたことを機に最新版へバージョンアップする作業を行っていたところ、

```
  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::                (v3.1.1)

Standard Commons Logging discovery in action with spring-jcl: please remove commons-logging.jar from classpath in order to avoid potential conflicts
```

起動時に警告が出てきました。

## Standard Commons Logging discovery in action with spring-jcl

```
Standard Commons Logging discovery in action with spring-jcl: please remove commons-logging.jar from classpath in order to avoid potential conflicts
```

警告文をそのままdeepl翻訳にかけてみると以下のようになります。

```
spring-jclで動作する標準的なコモンズロギングの発見：潜在的な競合を避けるために、クラスパスからcommons-logging.jarを削除してください。
```

警告文自体はロギング周りの設定に関することのようです。  
文章に素直に従えばcommons-loggingの依存を除外することで解消しそうですが、まずはその前に、何故この警告が出てきたのかを調べてみることにします。  
場当たり的に対処して他のバグが発生しても本末転倒なので。

## 調査

とはいえ、この状態で何か動作に問題があるという訳ではなかったので、本当に警告文以外にはとっかかりがない状態でした。

ひとまず調べたのはSpring Bootのリリースノート。

https://github.com/spring-projects/spring-boot/releases/tag/v3.1.1

ですが、更新内容はバグ修正のみで、こちらには特に今回の原因になりそうなものはありませんでした。

続いてはIssuesを調べてみます。
今回の場合は単にSpring Bootをバージョンアップしただけで起きた事象なので、同じことが起きているユーザもいるかと思ったのですが、

https://github.com/spring-projects/spring-boot/issues

こちらでもなんの情報も引っかかりません。
Spring Boot自体は特に問題となる箇所はなさそうだったので、対象を依存ライブラリまで広げて調べてみることにしました。

## 原因

そして、結論から言えば原因はやはりSpring Boot自体ではなく**Spring Framework**の方にありました。

https://github.com/spring-projects/spring-framework/issues/30575

上記のissuesを要約すると、

* Spring Flamework 5.0以降のspring-jclには、独自のCommons Loggingブリッジが付属している
  * 「org.apache.commons.logging.LogFactory」などのクラスが含まれている
* commons-loggingライブラリが他のライブラリの依存関係に含まれていると、spring-jclで指定しているクラスパスと重複してしまう
* そのままだとビルド時にエラーが発生する可能性があるため、Spring Framework 6.0.10からは、commons-loggingライブラリを使用している際に警告を表示するようになった

とのこと。
つまりは、Spring独自のロギングライブラリであるspring-jclが、commons-loggingとクラスパスが重複しているのが根本的な原因のようです。  
Spring Framework 6.0.10はSpring Boot3.1.1から使われているので、このバージョン以降では警告が出るようになった、というのが結論でした。

## 対策

結局対策としては最初に書いたとおり、  
既存の依存関係から`commons-logging`を除外すれば大丈夫です。

```gradle:build.gradle
configurations.configureEach {
    exclude group: 'commons-logging', module: 'commons-logging'
}
```

既存の依存関係から`commons-logging`を一括で削除し、改めて起動してみたところ...

```
  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::                (v3.1.1)
```

警告メッセージは出なくなりました！
動作確認はしっかり行い、特にデグレも起きていないので対策は完了です。

## まとめ
  
今回はSpring Bootをバージョンアップした際に出るようになった警告文の原因を深掘りしてみました。
結果的にはただ警告ログが出てきただけで少なくとも見える範囲では実害はなかったのですが、それでも警告が垂れ流しになっているのは気持ち悪かったので対策できてホッとしました。
バージョンアップの際は影響のなさそうなログもしっかり監視するようにしましょう。