JUnit
hamcrest

org.hamcrest.CoreMatchers#hasItem()等が見つからずにコンパイルエラーになる問題の解決方法

More than 3 years have passed since last update.

問題

JUnitは4.4からhamcrestを内包するようになりました。4.4のCoreMatchersにあるAPIのみを使っている場合は特に問題なかったのですが、CoreMatchers#hasItemなど、4.4がリリースされた以降に追加されたAPIを使うと、クラスパスの指定順でAPIがうまく解決できない事があります。

どういうこと?

例えばMavenの場合、各ライブラリに設定された依存関係を元にクラスパスを決定しますが、ライブラリごとに依存関係が設定できる事が原因で、古いCoreMatchersを先に参照してしまう事があります。Javaはコンパイル時に同じFQCNのクラスを複数ロードできないため、古いCoreMachersを先に参照してしまうと、新たにAPIが追加された方を参照できず、コンパイルエラーになります。

解決方法

JUnit 4.11以降はjunitというartifact idの方もhamcrestを内包せず、JUnitのdependencyに指定されることになりました。Mavenを利用しているユーザーであれば、

$ mvn dependency:tree

で依存関係を確認し、junitやhamcrestの古いバージョンを参照しているライブラリがあれば

pom.xml
...
<dependencies>
  <dependency>
    <groupId>GROUP_ID</groupId>
    <artifactId>ARTIFACT_ID</artifactId>
    <version>VERSION</version>
    <scope>provided</scope>
    <exclusions>
      <exclusion>
        <groupId>org.hamcrest</groupId>
        <artifactId>hamcrest-all</artifactId>
      </exclusion>
    </exclusions>
  </dependency>
</dependencies>
...
</project>

というようにexclusionを指定しましょう。