jenkinsでmvnのクラスパス重複が起きた場合の対処(Class path contains multiple ○○ bindings.)

Pocket

jenkins/mavenの組み合わせで勉強中。

以下の書籍に沿って勉強しているのですが、メトリクスの追加部分でエラーが起きました。

【症状】
jenkinsでジョブ実行時、コンソールに以下のエラーが表示される。

[ERROR] SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:/var/lib/jenkins/.m2/repository/ch/qos/logback/logback-classic/1.0.13/logback-classic-1.0.13.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/var/lib/jenkins/.m2/repository/org/slf4j/slf4j-simple/1.6.1/slf4j-simple-1.6.1.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]

jenkinsのプラグインの管理から「Cobertura Plugin」を追加し、
ビルド後の処理で「Coberturaカバレッジレポートの集計」を追加したら発生しました。

とりあえず対応手順としては、以下。
 ①重複しているjarが何か調べる
 ②①のjarを依存指定しているpomを探す
 ③除外設定する

色々苦労した割に、結局はサンプルソースのpomを一カ所直すだけでした・・・。

膨大になった作業ログは経緯や手順などの備忘として一応残しておきますが、必要なかった対応です。

とりあえず先に解決策。

jenkinsのジョブ結果をコンソール出力すると、以下の行の下でエラーが発生している。

[INFO] --- cobertura-maven-plugin:2.7:instrument (default-cli) @ gameoflife-web ---

以下の3箇所ではエラーは起きていない。

[INFO] --- cobertura-maven-plugin:2.7:instrument (default-cli) @ gameoflife-build ---
[INFO] --- cobertura-maven-plugin:2.7:instrument (default-cli) @ gameoflife-core ---
[INFO] --- cobertura-maven-plugin:2.7:instrument (default-cli) @ gameoflife ---

「gameoflife-web」に何か問題があると推察し、以下を実行。

sudo vi ~/jenkinsprj/game-of-life/gameoflife-web/pom.xml

slf4jの指定を見付けたのでコメントアウト。

GitHubのファイルを更新。

git commit -a -m "適当な文言"
git push

GitHubのサイトから更新されている事を確認。

jenkinsのジョブを実行。

エラーは消えましたが、カバレッジファイルは出ないので、また別途調査します。

ここから下は完全に備忘のための作業ログです。今回の問題とは全く関係のない変な対応をしておりますので、ご注意ください。
後で全て設定戻したところエラーは起きず、全くもってプラグイン側のpomを修正する必要はないようでした・・・。


【症状】
jenkinsでジョブ実行時、コンソールに以下のエラーが表示される。

[ERROR] SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:/var/lib/jenkins/.m2/repository/ch/qos/logback/logback-classic/1.0.13/logback-classic-1.0.13.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/var/lib/jenkins/.m2/repository/org/slf4j/slf4j-simple/1.6.1/slf4j-simple-1.6.1.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]

jenkinsのプラグインの管理から「Cobertura Plugin」を追加し、
ビルド後の処理で「Coberturaカバレッジレポートの集計」を追加したら発生しました。

エラーメッセージから、クラスパスでSLF4J(ログのjar)が重複して指定されている事は理解。

ネットで色々調べると、どうもmavenで使うpomファイル内でjarを指定しており、slf4jで重複がある模様。
対応としては重複箇所の<dependencies>タグ内に以下の記述を入れれば、重複した読み込みはなくなるとのこと。
※以下、<groupId>や<artifactId>は重複したものに応じて異なる。

    <exclusions>
      <exclusion>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-log4j12</artifactId>
      </exclusion>
      <exclusion>
        <groupId>log4j</groupId>
        <artifactId>log4j</artifactId>
      </exclusion>
    </exclusions>

※参考URL:http://www.slf4j.org/codes.html#multiple_bindings

さて、問題はどこのpomのどの<dependencies>で重複しているのか。

まず、jenkinsで自動インストールしたmavenのmvnコマンドの場所は以下。
/var/lib/jenkins/tools/hudson.tasks.Maven_MavenInstallation/Maven名称/bin/mvn

○依存関係を確認
・リポジトリの場所(pom.xmlがある場所)に移動

cd ~/jenkinsprj/game-of-life

・依存関係を確認

/var/lib/jenkins/tools/hudson.tasks.Maven_MavenInstallation/Maven名称/bin/mvn dependency:tree

・なんかエラー出たので、とりあえずクリーンとインストール

/var/lib/jenkins/tools/hudson.tasks.Maven_MavenInstallation/Maven名称/bin/mvn clean isntall

・もっかい依存関係を確認

/var/lib/jenkins/tools/hudson.tasks.Maven_MavenInstallation/Maven名称/bin/mvn dependency:tree

<実行結果>

Picked up JAVA_TOOL_OPTIONS: -javaagent:/usr/share/java/jayatanaag.jar 
[INFO] Scanning for projects...
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Build Order:
[INFO] 
[INFO] gameoflife
[INFO] gameoflife-build
[INFO] gameoflife-core
[INFO] gameoflife-web
[INFO]                                                                         
[INFO] ------------------------------------------------------------------------
[INFO] Building gameoflife 1.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO] 
[INFO] --- maven-dependency-plugin:2.8:tree (default-cli) @ gameoflife ---
[INFO] com.wakaleo.gameoflife:gameoflife:pom:1.0-SNAPSHOT
[INFO] +- junit:junit:jar:4.11:test
[INFO] |  \- org.hamcrest:hamcrest-core:jar:1.3:test
[INFO] +- org.hamcrest:hamcrest-all:jar:1.1:test
[INFO] \- org.mockito:mockito-all:jar:1.9.0:test
[INFO]                                                                         
[INFO] ------------------------------------------------------------------------
[INFO] Building gameoflife-build 1.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO] 
[INFO] --- maven-dependency-plugin:2.8:tree (default-cli) @ gameoflife-build ---
[INFO] com.wakaleo.gameoflife:gameoflife-build:jar:1.0-SNAPSHOT
[INFO] +- junit:junit:jar:4.11:test
[INFO] |  \- org.hamcrest:hamcrest-core:jar:1.3:test
[INFO] +- org.hamcrest:hamcrest-all:jar:1.1:test
[INFO] \- org.mockito:mockito-all:jar:1.9.0:test
[INFO]                                                                         
[INFO] ------------------------------------------------------------------------
[INFO] Building gameoflife-core 1.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO] 
[INFO] --- maven-dependency-plugin:2.8:tree (default-cli) @ gameoflife-core ---
[INFO] com.wakaleo.gameoflife:gameoflife-core:jar:1.0-SNAPSHOT
[INFO] +- junit:junit:jar:4.11:test
[INFO] |  \- org.hamcrest:hamcrest-core:jar:1.3:test
[INFO] +- org.hamcrest:hamcrest-all:jar:1.1:test
[INFO] \- org.mockito:mockito-all:jar:1.9.0:test
[INFO]                                                                         
[INFO] ------------------------------------------------------------------------
[INFO] Building gameoflife-web 1.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO] 
[INFO] --- maven-dependency-plugin:2.8:tree (default-cli) @ gameoflife-web ---
[INFO] com.wakaleo.gameoflife:gameoflife-web:war:1.0-SNAPSHOT
[INFO] +- com.wakaleo.gameoflife:gameoflife-core:jar:1.0-SNAPSHOT:compile
[INFO] +- org.springframework:spring-webmvc:jar:3.0.2.RELEASE:compile
[INFO] |  +- org.springframework:spring-asm:jar:3.0.2.RELEASE:compile
[INFO] |  +- org.springframework:spring-beans:jar:3.0.2.RELEASE:compile
[INFO] |  +- org.springframework:spring-context:jar:3.0.2.RELEASE:compile
[INFO] |  |  \- org.springframework:spring-aop:jar:3.0.2.RELEASE:compile
[INFO] |  +- org.springframework:spring-context-support:jar:3.0.2.RELEASE:compile
[INFO] |  \- org.springframework:spring-expression:jar:3.0.2.RELEASE:compile
[INFO] +- org.springframework:spring-core:jar:3.0.2.RELEASE:compile
[INFO] |  \- commons-logging:commons-logging:jar:1.1.1:compile
[INFO] +- org.springframework:spring-web:jar:3.0.2.RELEASE:compile
[INFO] |  \- aopalliance:aopalliance:jar:1.0:compile
[INFO] +- javax.servlet:jstl:jar:1.2:compile
[INFO] +- javax.servlet:servlet-api:jar:2.5:provided
[INFO] +- org.mockito:mockito-all:jar:1.8.5:test
[INFO] +- org.easytesting:fest-assert:jar:1.4:compile
[INFO] |  \- org.easytesting:fest-util:jar:1.1.6:compile
[INFO] +- org.slf4j:slf4j-simple:jar:1.6.1:compile
[INFO] +- org.slf4j:slf4j-api:jar:1.6.1:compile
[INFO] +- junit:junit:jar:4.11:test
[INFO] |  \- org.hamcrest:hamcrest-core:jar:1.3:test
[INFO] \- org.hamcrest:hamcrest-all:jar:1.1:test
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Summary:
[INFO] 
[INFO] gameoflife ......................................... SUCCESS [  2.697 s]
[INFO] gameoflife-build ................................... SUCCESS [  0.096 s]
[INFO] gameoflife-core .................................... SUCCESS [  0.032 s]
[INFO] gameoflife-web ..................................... SUCCESS [  0.292 s]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 5.008 s
[INFO] Finished at: 2015-10-01T06:38:07+09:00
[INFO] Final Memory: 18M/163M
[INFO] ------------------------------------------------------------------------

どうも「gameoflife-web」にslf4jがあるっぽい?1つしかないし、プロジェクト以外のpomに重複あるのかな。
そもそもプロジェクト自体が書籍のサンプルコードだから全容をよく理解できていないのですが。

とりあえず「gameoflife-web」とプラグイン「Cobertura」内の両方でslf4jが指定されているのなと思いながら、
今度は「Cobertura」が<dependency>で指定されているpomはどこなのか考える。

以下にプラグイン「Dozer」で同様の症状に対応した記事を発見。
しかしどこのpomを編集して対応したのか分からず。
※参考URL:http://kikutaro777.hatenablog.com/entry/2013/05/29/211405

とりあえずファイル名に「pom」を含むものを探す。
・リポジトリの場所(pom.xmlがある場所)に移動

cd ~/jenkinsprj/game-of-life

・pomを含むファイル名を探す

find -iname *pom*

<実行結果>

./gameoflife-web/pom.xml
./gameoflife-deploy/pom.xml
./pom.xml
./gameoflife-acceptance-tests/pom.xml
./gameoflife-build/pom.xml
./gameoflife-core/pom.xml

ファイル内を見ましたが、「cobertura」は<plugin>で指定されてますが、<dependency>で指定されておらず。

次にファイル内容に「cobertura」を含むファイルを検索

find ./ -type f -print | xargs grep "cobertura"

<実行結果>
※見づらいのでエラー結果は省略

./pom.xml:        <cobertura.version>2.6</cobertura.version>
./pom.xml:                        <artifactId>cobertura-maven-plugin</artifactId>
./pom.xml:                        <version>${cobertura.version}</version>
./test:        <cobertura.version>2.6</cobertura.version>
./test:                        <artifactId>cobertura-maven-plugin</artifactId>
./test:                        <version>${cobertura.version}</version>
./test:                <artifactId>cobertura-maven-plugin</artifactId>
./gameoflife-core/pom.xml:                <artifactId>cobertura-maven-plugin</artifactId>

「./pom.xml」、「./test」、「./gameoflife-core/pom.xml」ファイル内を確認しましたが、
やはり「cobertura」を<dependency>で指定している記述はない。

もしかしてjenkins(プラグイン)側で指定している?
とりあえず「/var/lib/jenkins/plugins」内で、ファイル内容に「<artifactId>cobertura</artifactId>」を含む箇所を検索
※「cobertura」で検索したら表示量がえらいことになった・・・

※「cobertura」で検索したら表示量がえらいことになった・・・
sudo find /var/lib/jenkins/ -type f -print | xargs grep "<artifactId>cobertura</artifactId>"

<実行結果>
※見づらいのでエラー結果は省略

/var/lib/jenkins/.m2/repository/net/sourceforge/cobertura/cobertura-runtime/2.1.1/cobertura-runtime-2.1.1.pom:      <artifactId>cobertura</artifactId>
/var/lib/jenkins/.m2/repository/net/sourceforge/cobertura/cobertura/2.1.1/cobertura-2.1.1.pom:  <artifactId>cobertura</artifactId>
/var/lib/jenkins/.m2/repository/org/codehaus/mojo/cobertura-maven-plugin/2.7/cobertura-maven-plugin-2.7.pom:      <artifactId>cobertura</artifactId>
/var/lib/jenkins/plugins/cobertura/META-INF/maven/org.jenkins-ci.plugins/cobertura/pom.xml:  <artifactId>cobertura</artifactId>

ファイル内を確認し、以下の中に<dependency>で「cobertura」を指定している箇所を発見

/var/lib/jenkins/.m2/repository/net/sourceforge/cobertura/cobertura-runtime/2.1.1/cobertura-runtime-2.1.1.pom
/var/lib/jenkins/.m2/repository/org/codehaus/mojo/cobertura-maven-plugin/2.7/cobertura-maven-plugin-2.7.pom

果たしてこれは修正して良いファイルなのか・・・。
リポジトリって書いてあるけど、元のファイルを修正しないと元に戻るのではないかとか、知識不足過ぎて何も分からない。

再度ネットで検索。
エラーメッセージとか区切らず””で囲ってダイレクトな情報を探すと、海外で全く同じ状況(coberturaでクラスパス重複エラー)の記事を発見。
※参考URL:http://answeruxu.livedoor.biz/archives/1038955959.html

しかも同じ書籍(海外版)を利用して、同じエラーが起きて困っている事に苦笑。
記事を書いた人は多分、slf4j自体の<dependency>から<exclusion>でslf4jを除外しようとしているので、
解答ではちゃんとslf4jに依存してる別の<dependency>でslf4jを除外しなさい、でも依存してるjarが何か分からないから対応できない。
とか言われてる。

気になるのは「logback-classic」の依存がどこか問われているところ。

今度は「logback-classic」を検索ワードに入れてエラーメッセージとともに検索。
それっぽい記事を発見。しかもcobertura-runtimeの<dependency>からlogback-classicを<exclusion>している。
参考URL:https://github.com/mojohaus/cobertura-maven-plugin/issues/6

しかも<exclusion>を使っている対象は「cobertura-runtime」と「coberetura」なので、やっぱりさっきのファイル直せばいいのか!?

修正してみる。
改行コードが違うらしく行末に^Mとか入っているけど気にしない。

sudo vi /var/lib/jenkins/.m2/repository/org/codehaus/mojo/cobertura-maven-plugin/2.7/cobertura-maven-plugin-2.7.pom

以下のように編集(ハイライト部分が追記した箇所)。
行末にも一応同じ改行コードをコピペで入れておく。

    ^M
      net.sourceforge.cobertura^M
      cobertura-runtime^M
      ${coberturaVersion}^M
      pom^M
      ^M
        ^M
          ch.qos.logback^M
          logback-classic^M
        ^M
      ^M
    ^M
    ^M
      net.sourceforge.cobertura^M
      cobertura^M
      ${coberturaVersion}^M
        ^M
            ^M
                jaxen^M
                jaxen^M
            ^M
            ^M
                xerces^M
                xercesImpl^M
            ^M
            ^M
              ch.qos.logback^M
              logback-classic^M
            ^M
        ^M
    ^M

もう1ファイルも見てみる。

sudo vi /var/lib/jenkins/.m2/repository/net/sourceforge/cobertura/cobertura-runtime/2.1.1/cobertura-runtime-2.1.1.pom

こっちにも<dependency>のcoberturaがある…直すのだろうか。とりあえず一度、動作を確認してみる事にする。

jenkinsからジョブを実行したが、エラー変わらず。
よってもう1ファイルも編集する。(適当感が・・・)

sudo vi /var/lib/jenkins/.m2/repository/net/sourceforge/cobertura/cobertura-runtime/2.1.1/cobertura-runtime-2.1.1.pom

以下、編集内容。

    ^M
      net.sourceforge.cobertura^M
      cobertura^M
      ${project.version}^M
      ^M
        ^M
          org.ow2.asm^M
          asm^M
        ^M
        ^M
          org.ow2.asm^M
          asm-tree^M
        ^M
        ^M
          org.ow2.asm^M
          asm-commons^M
        ^M
        ^M
          org.ow2.asm^M
          asm-util^M
        ^M
        ^M
          org.ow2.asm^M
          asm-analysis^M
        ^M
        ^M
          oro^M
          oro^M
        ^M
        ^M
          ch.pos.logback^M
          logback-classic^M
        ^M
      ^M
    ^M

再度、jenkinsからジョブを実行。祈る。

直らない・・・どゆことさ。

もしかして「logback-classic」が被ってるなら、ファイル内容を「cobertura」でなくて「logback-classic」で探してみたらいい?

sudo find /var/lib/jenkins/ -type f -print | xargs grep "&lt;artifactId&gt;logback-classic&lt;/artifactId&gt;"

<実行結果>

/var/lib/jenkins/.m2/repository/ch/qos/logback/logback-classic/1.0.13/logback-classic-1.0.13.pom:  <artifactId>logback-classic</artifactId>
/var/lib/jenkins/.m2/repository/ch/qos/logback/logback-parent/1.0.13/logback-parent-1.0.13.pom:        <artifactId>logback-classic</artifactId>
/var/lib/jenkins/.m2/repository/net/thucydides/thucydides/0.9.268/thucydides-0.9.268.pom:            <artifactId>logback-classic</artifactId>
/var/lib/jenkins/.m2/repository/net/sourceforge/cobertura/cobertura-runtime/2.1.1/cobertura-runtime-2.1.1.pom:          <artifactId>logback-classic</artifactId>
/var/lib/jenkins/.m2/repository/net/sourceforge/cobertura/cobertura/2.1.1/cobertura-2.1.1.pom:      <artifactId>logback-classic</artifactId>
/var/lib/jenkins/.m2/repository/org/apache/jackrabbit/jackrabbit-webdav/2.2.5/jackrabbit-webdav-2.2.5.pom:      <artifactId>logback-classic</artifactId>
/var/lib/jenkins/.m2/repository/org/apache/jackrabbit/jackrabbit-parent/2.2.5/jackrabbit-parent-2.2.5.pom:        <artifactId>logback-classic</artifactId>
/var/lib/jenkins/.m2/repository/org/codehaus/mojo/cobertura-maven-plugin/2.7/cobertura-maven-plugin-2.7.pom:              <artifactId>logback-classic</artifactId>
/var/lib/jenkins/.m2/repository/org/codehaus/mojo/cobertura-maven-plugin/2.7/cobertura-maven-plugin-2.7.pom:          <artifactId>logback-classic</artifactId>

またいっぱい出たこと・・・9ファイルですか。とりあえずlogback本体っぽいのは除いて、coberturaはさっき直したので、実質以下の3ファイルかな。

/var/lib/jenkins/.m2/repository/org/apache/jackrabbit/jackrabbit-webdav/2.2.5/jackrabbit-webdav-2.2.5.pom
/var/lib/jenkins/.m2/repository/org/apache/jackrabbit/jackrabbit-parent/2.2.5/jackrabbit-parent-2.2.5.pom
/var/lib/jenkins/.m2/repository/net/thucydides/thucydides/0.9.268/thucydides-0.9.268.pom

viで見てみると、確かに全ファイル<dependency>でlogback-classicが指定されている。
ここに<exclusion>書いたらさっきの海外の人と同じになるので意味ないから・・・と考えていて気付く。

ああ、つまり「logback-classic」に依存する記述があるライブラリを探して、そのライブラリを<dependency>で設定している箇所に除外する設定を書けばいいのね。

依存の問題があるライブラリを見付けても、そのライブラリに依存する末端を探さないといけないのか。
というわけで今度は「jackrabbit-webdav」、「jackrabbit-parent」、「thucydides」というワードで検索。

まずは「jackrabbit-webdav」から検索。

sudo find /var/lib/jenkins/ -type f -print | xargs grep "<artifactId>jackrabbit-webdav</artifactId>"

<実行結果>

/var/lib/jenkins/.m2/repository/org/apache/maven/wagon/wagon-webdav-jackrabbit/2.2/wagon-webdav-jackrabbit-2.2.pom:      <artifactId>jackrabbit-webdav</artifactId>
/var/lib/jenkins/.m2/repository/org/apache/maven/plugins/maven-site-plugin/3.3/maven-site-plugin-3.3.pom:          <artifactId>jackrabbit-webdav</artifactId>
/var/lib/jenkins/.m2/repository/org/apache/jackrabbit/jackrabbit-webdav/2.2.5/jackrabbit-webdav-2.2.5.pom:  <artifactId>jackrabbit-webdav</artifactId>

viで確認しつつ、ファイルを直していく。
(3ファイル中、実際に<dependency>でjackrabbit-webdavを指定していたのは1ファイルだけだった)

sudo vi /var/lib/jenkins/.m2/repository/org/apache/maven/wagon/wagon-webdav-jackrabbit/2.2/wagon-webdav-jackrabbit-2.2.pom

修正内容は以下。

  
    
      ${project.groupId}
      wagon-http-shared
      ${project.version}
    
    
      org.apache.jackrabbit
      jackrabbit-webdav
      2.2.5
      
        
          commons-logging
          commons-logging
        
        
          ch.qos.logback
          logback-classic
        
      
    

次に「jackrabbit-parent」を検索。

sudo find /var/lib/jenkins/ -type f -print | xargs grep "<artifactId>jackrabbit-parent</artifactId>"

<実行結果>

/var/lib/jenkins/.m2/repository/org/apache/jackrabbit/jackrabbit-webdav/2.2.5/jackrabbit-webdav-2.2.5.pom:    <artifactId>jackrabbit-parent</artifactId>
/var/lib/jenkins/.m2/repository/org/apache/jackrabbit/jackrabbit-jcr-commons/2.2.5/jackrabbit-jcr-commons-2.2.5.pom:    <artifactId>jackrabbit-parent</artifactId>
/var/lib/jenkins/.m2/repository/org/apache/jackrabbit/jackrabbit-parent/2.2.5/jackrabbit-parent-2.2.5.pom:  <artifactId>jackrabbit-parent</artifactId>

ここは修正の必要なかった。

最後に「thucydides」で検索。

sudo find /var/lib/jenkins/ -type f -print | xargs grep "<artifactId>thucydides</artifactId>"

<実行結果>

/var/lib/jenkins/.m2/repository/org/apache/jackrabbit/jackrabbit-webdav/2.2.5/jackrabbit-webdav-2.2.5.pom:    <artifactId>jackrabbit-parent</artifactId>
/var/lib/jenkins/.m2/repository/org/apache/jackrabbit/jackrabbit-jcr-commons/2.2.5/jackrabbit-jcr-commons-2.2.5.pom:    <artifactId>jackrabbit-parent</artifactId>
/var/lib/jenkins/.m2/repository/org/apache/jackrabbit/jackrabbit-parent/2.2.5/jackrabbit-parent-2.2.5.pom:  <artifactId>jackrabbit-parent</artifactId>

ここで1箇所、「thucydides-core-0.9.268.pom」と「maven-thucydides-plugin-0.9.268.pom」、「thucydides-report-resources-0.9.268.pom」にて以下の記述が気になる。

<parent>
  <artifactId...
</parent>

どうも「thucydides-0.9.268.pom」の設定を引き継いでいるらしい。
んでもって、「thucydides-0.9.268.pom」には「logback-classic」を<dependency>で指定する記述がある。
ということは上記の3ファイルはthucydidesを<exclusion>する必要がある?

とりあえずこっちは放っておいて、リポジトリの方でも「logback-classic」を探してみる。

再度、jenkinsからジョブを実行。再び祈る。

エラー変わらず・・・そして前の設定内容でスペルミスがあったので修正。
(※上に書いた分は修正済みの設定内容です)

jenkinsからジョブを実行。

エラーが変わった!!
以下みたいなエラーメッセージが大量に出ている。

[ERROR] SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.

これはlogback-classicを全部除外したからっぽいね!!

とりあえず「cobertura-maven-plugin-2.7.pom」だけ元に戻してみる。

sudo vi /var/lib/jenkins/.m2/repository/org/codehaus/mojo/cobertura-maven-plugin/2.7/cobertura-maven-plugin-2.7.pom

以下のように編集。

    ^M
      net.sourceforge.cobertura^M
      cobertura-runtime^M
      ${coberturaVersion}^M
      pom^M
      ^M
        ^M
          ch.qos.logback^M
          logback-classic^M
        ^M
      ^M
    ^M

    ^M
      net.sourceforge.cobertura^M
      cobertura^M
      ${coberturaVersion}^M
        ^M
            ^M
                jaxen^M
                jaxen^M
            ^M
            ^M
                xerces^M
                xercesImpl^M
            ^M
^M
        ^M
    ^M

jenkinsからジョブを実行。

あれ・・・またメッセージがクラスパス重複になってしまった。
しかも元に戻すと、再びslf4jのロードエラー。

これはcoberturaがどこか複数個所で呼ばれているのだろうか・・・うーん、だとしたら「cobertura-maven-plugin-2.7.pom」内の
cobertura-runtimeの方の除外だけ消せばよい?やってみると、やはりslf4jのロードエラー。

とりあえずファイル内容を以下に戻して、他に「cobertura」に依存しているpomがないか探す。

sudo find /var/lib/jenkins/ -type f -print | xargs grep "&lt;artifactId&gt;cobertura&lt;/artifactId&gt;"

<実行結果>

/var/lib/jenkins/.m2/repository/net/sourceforge/cobertura/cobertura-runtime/2.0.3/cobertura-runtime-2.0.3.pom:      <artifactId>cobertura</artifactId>
/var/lib/jenkins/.m2/repository/net/sourceforge/cobertura/cobertura-runtime/2.1.1/cobertura-runtime-2.1.1.pom:          <artifactId>cobertura</artifactId>
/var/lib/jenkins/.m2/repository/net/sourceforge/cobertura/cobertura/2.0.3/cobertura-2.0.3.pom:  <artifactId>cobertura</artifactId>
/var/lib/jenkins/.m2/repository/net/sourceforge/cobertura/cobertura/2.1.1/cobertura-2.1.1.pom:  <artifactId>cobertura</artifactId>
/var/lib/jenkins/.m2/repository/org/codehaus/mojo/cobertura-maven-plugin/2.7/cobertura-maven-plugin-2.7.pom:      <artifactId>cobertura</artifactId>
/var/lib/jenkins/.m2/repository/org/codehaus/mojo/cobertura-maven-plugin/2.6/cobertura-maven-plugin-2.6.pom:      <artifactId>cobertura</artifactId>
/var/lib/jenkins/plugins/cobertura/META-INF/maven/org.jenkins-ci.plugins/cobertura/pom.xml:  <artifactId>cobertura</artifactId>

viで上記7ファイルを確認。
「cobertura-runtime-2.0.3.pom」と「cobertura-maven-plugin-2.6.pom」の中に<dependency>でcoberturaの指定を発見。

とりあえず両方修正。

sudo vi /var/lib/jenkins/.m2/repository/net/sourceforge/cobertura/cobertura-runtime/2.0.3/cobertura-runtime-2.0.3.pom

修正内容は以下。

    
      net.sourceforge.cobertura
      cobertura
      2.0.3
      
        
          oro
          oro
        
        
          asm
          asm
        
        
          asm
          asm-tree
        
        
          asm
          asm-commons
        
        
          log4j
          log4j
        
        
          ch.qos.logback
          logback-classic
        
      
    
sudo vi /var/lib/jenkins/.m2/repository/org/codehaus/mojo/cobertura-maven-plugin/2.6/cobertura-maven-plugin-2.6.pom

修正内容は以下。

    
      net.sourceforge.cobertura
      cobertura
      ${coberturaVersion}
      
        
          ch.qos.logback
          logback-classic
        
      
    

jenkinsからジョブを実行。

またクラスパス重複エラー。

混乱してきたので、状況を整理する。

【状況】
・ファイル「/var/lib/jenkins/.m2/repository/org/codehaus/mojo/cobertura-maven-plugin/2.7/cobertura-maven-plugin-2.7.pom」の
<dependency>で指定されたcobertura/cobertura-runtimeの箇所で

coberturaでlogbackの除外あり coberturaでlogbackの除外なし
coberturaでlogbackの除外あり slf4jのロードエラー slf4jのクラスパス重複エラー
coberturaでlogbackの除外なし slf4jのロードエラー slf4jのクラスパス重複エラー

改めて確認してみるが、上記の通りに動く。

これはどう見ても「cobertura」のlogback有無によって挙動が決まっている・・・。
今の知識で思いつくのは以下の理由。
(1)coberturaに依存する設定が複数個所にある
(2)cobertura自体にクラスパス重複設定がある

とりあえず(1)は対応したつもりなので、(2)と推察して対応してみる。
ファイル「cobertura-maven-plugin-2.7.pom」で、coberturaはlogbackの除外をせず、cobertura-runtimeのみ除外設定を入れた。

先だって「cobertura」という文字列でファイル内容を検索した結果で、以下ファイルが該当していたのでファイルを編集。

/var/lib/jenkins/.m2/repository/net/sourceforge/cobertura/cobertura/2.1.1/cobertura-2.1.1.pom "<artifactId>cobertura</artifactId>"
sudo vi /var/lib/jenkins/.m2/repository/net/sourceforge/cobertura/cobertura/2.1.1/cobertura-2.1.1.pom

<修正内容>

^M

上記の状態でjenkinsのジョブを実行すると、slf4jのロードエラーになる。
これをもとに戻し、今度は以下をコメントアウトしてジョブを実行すると、sl4jのクラスパス重複エラーになる。

^M

んー、slf4j-apiは関係なし。
<artifactId>tools</artifactId>も除外してみたけど変わらず重複エラー。

そういえばjenkinsのジョブ実行結果(コンソール出力)に出てくるエラーは以下。(抜粋)

[INFO] --- cobertura-maven-plugin:2.7:instrument (default-cli) @ gameoflife-web ---
[INFO] Cobertura 2.1.1 - GNU GPL License (NO WARRANTY) - See COPYRIGHT file
[INFO] Cobertura: Saved information on 2 classes.
[INFO] Cobertura: Saved information on 2 classes.

[ERROR] SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:/var/lib/jenkins/.m2/repository/ch/qos/logback/logback-classic/1.0.13/logback-classic-1.0.13.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/var/lib/jenkins/.m2/repository/org/slf4j/slf4j-simple/1.6.1/slf4j-simple-1.6.1.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]

特に以下の行の下でエラーが発生している事に気付く。

[INFO] --- cobertura-maven-plugin:2.7:instrument (default-cli) @ gameoflife-web ---

以下の3箇所ではエラーは起きていない。

[INFO] --- cobertura-maven-plugin:2.7:instrument (default-cli) @ gameoflife-build ---
[INFO] --- cobertura-maven-plugin:2.7:instrument (default-cli) @ gameoflife-core ---[/bash</pre>
<pre>[INFO] --- cobertura-maven-plugin:2.7:instrument (default-cli) @ gameoflife ---

これは・・・「gameoflife-web」に何か問題があるのか?

sudo vi ~/jenkinsprj/game-of-life/gameoflife-web/pom.xml

slf4jの指定を見付けたのでコメントアウト。

またjenkinsのジョブを実行したけど、重複エラー。

Gitのファイルを更新していない事に気付く。

git commit -a -m "適当な文言"
git push

GitHubのサイトから更新されている事を確認。

jenkinsのジョブを実行。

エラーが消えた!!

相変わらずビルド履歴のアイコンが赤いのは、初回カバレッジファイルがないから?
もう一度ジョブを実行!!

消えない・・・今度は何だ!!

どうやらjenkinsのジョブ設定「成果物を保存」の保存するファイルのパスがまずい様子。

もしかして今回「mvn clean test」とかってゴールだから問題があるの?
とりあえず「mvn clean package」にしてみる。

安定ビルドになった。

あー、もしかして書籍に書いてある内容をどんどん同じジョブに追記・変更していってたけど、
過去の内容は都度消したりしながら進めないといけないのかな……そんなの分からないよー。

なんとなくjenkinsにお願いするジョブ内容によって、mvnのゴールを変えないといけない予感もする。

とりあえずエラーは解消したけど、無駄に設定変えてないか確認しないといけない。

あと安定ビルドにできたけど、カバレッジ・レポートが存在しないらしい。

これはまた別の問題だと思うので、今度対応します。

広告

Pocket

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です