組織独自のユーティリティ系のJava共通ライブラリを使って、開発を行っているのですが、そのJavaライブラリー内でのロギングでハマったことをまとめておこうと思います。
2つありました。
(1)SLF4J: Class path contains multiple SLF4J bindings.
MainのJavaアプリをbuildした際に出てきたエラー・メッセージです。
SLF4J: Class path contains multiple SLF4J bindings. SLF4J: Found binding in [jar:file:/C:/develops/java-commons/build/libs/java-commons-1.0.0.jar!/org/slf4j/impl/StaticLoggerBinder.class] SLF4J: Found binding in [jar:file:/C:/gradle/gradle-5.6.1/caches/modules-2/files-2.1/ch.qos.logback/logback-classic/1.2.3/7c4f3c474fb2c041d8028740440937705ebb473a/logback-classic-1.2.3.jar!/org/slf4j/impl/StaticLoggerBinder.class] SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation. SLF4J: Actual binding is of type [ch.qos.logback.classic.util.ContextSelectorStaticBinder]
配布パッケージの依存先からlogbackを取り除けばいいことを知り、独自のユーティリティ系のJavaライブラリー(commons)側の build.gradleを下記のように修正したら、エラーメッセージが出力されなくなりました。
configurations { provided } sourceSets { main.compileClasspath += configurations.provided test.compileClasspath += configurations.provided test.runtimeClasspath += configurations.provided } dependencies { compile 'org.slf4j:slf4j-api:1.7.28' //compile 'ch.qos.logback:logback-classic:1.2.3' // ↓ provided 'ch.qos.logback:logback-classic:1.2.3' testCompile group: 'junit', name: 'junit', version: '4.12' }
ビルドシステムについての理解が足りていない証拠でしょう。
(2)Resource [logback.xml] occurs multiple times on the classpath.
次の壁は、MainのJavaアプリとJavaライブラリーのそれぞれに、「logback.xml」が存在しているため、次のような警告が出力されました。
> Task :Main.main() INFO in ch.qos.logback.classic.LoggerContext[default] - Could NOT find resource [logback-test.xml] INFO in ch.qos.logback.classic.LoggerContext[default] - Could NOT find resource [logback.groovy] INFO in ch.qos.logback.classic.LoggerContext[default] - Found resource [logback.xml] at [file:/C:/develops/JavaMainApp/build/resources/main/logback.xml] WARN in ch.qos.logback.classic.LoggerContext[default] - Resource [logback.xml] occurs multiple times on the classpath. WARN in ch.qos.logback.classic.LoggerContext[default] - Resource [logback.xml] occurs at [file:/C:/develops/JavaMainApp/build/resources/main/logback.xml] WARN in ch.qos.logback.classic.LoggerContext[default] - Resource [logback.xml] occurs at [jar:file:/C:/develops/java-commons/build/libs/java-commons-1.0.0.jar!/logback.xml] INFO in ch.qos.logback.classic.joran.action.ConfigurationAction - debug attribute not set INFO in ch.qos.logback.core.joran.action.AppenderAction - About to instantiate appender of type [ch.qos.logback.core.ConsoleAppender]
期待する動きは、JavaMainAppを動かしたときに、JavaMainAppから吐き出されるログも、java-commonsから吐き出されるログも、すべてJavaMainAppのlogback.xmlで設定したファイルに出力させることでした。
警告ログからもわかるように、logback設定ファイルの検索順序は次の通りであるので、それぞれのプロジェクトごとにlogbackファイル名を変更して、挙動を試してみました。
選択肢 | java-commons | JavaMainApp | java-commons実行 | JavaMainApp実行 |
---|---|---|---|---|
A | logback.xml | logback.xml | java-commons設定のlog出力 | JavaMainApp設定のlog出力 ※WARN:Resource [logback.xml] occurs multiple times on the classpath. |
B | logback2.xml | logback.xml | log出力なし→ NG | JavaMainApp設定のlog出力 |
C | logback-test.xml | logback.xml | java-commons設定のlog出力 | java-commons設定のlog出力→ NG |
何か解決方法があるかもしれませんが、選択肢Aであれば期待する動きになるので(警告は毎回出ますが・・・)、とりあえずはこちらの設定で進めていこうと思っています。
また、新手のエラーが発生するかもしれませんが、「壁」は大いに結構です!!!
その壁を超える度に、強くなっていくつもりなので。
とりあえず、Gradleの勉強もやっていきましょうか。