NoSuchMethodError with Hamcrest 1.3 & JUnit 4.11

28,980

Solution 1

This blog helped fix the same problem for me:

https://tedvinke.wordpress.com/2013/12/17/mixing-junit-hamcrest-and-mockito-explaining-nosuchmethoderror/

Inside the dependencies for Mockito and Junit, the author added excludes:

<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.11</version>
    <exclusions>
        <exclusion>
            <artifactId>hamcrest-core</artifactId>
            <groupId>org.hamcrest</groupId>
        </exclusion>
    </exclusions>
</dependency>

Solution 2

What worked for me was to reorder dependencies. Instead of going mockito, junit, I had to put junit, mockito.

Mockito 1.9.5 uses hamcrest 1.1 which is incompatible and causes problems.

Solution 3

Using David's tip and How do I split a string on a delimiter in Bash? resulted in the following bash script:

( IFS=":"; for i in `mvn dependency:build-classpath | grep -v '\[INFO\]'`; do jar tf $i | awk "{print \"$i\\t\" \$1}"; done | grep Matcher )

(online at http://www.kaspervandenberg.net/2013/scripts/findDependencyClass.sh)

Which found that dependency JGlobus-Core-2.0.4 has its own versions of org.hamcrest.BaseMatcher, org.hamcrest.CoreMatchers, and org.hamcrest.Matcher.

Solution 4

If you are using Eclipse, the "Open Type" tool (CTRL+SHIFT+T) can help you find the problematic package. Just search for the class name (e.g., Description), multiple occurrences of the same class from different JARs are red flags.

Solution 5

Perhaps one of those other JARs has older versions of Hamcrest's Matcher or BaseMatcher. Here's a list of JARs which include the latter, though I have no idea how comprehensive that site is. Is there a Maven plugin which will show you all the dependencies that include a class similar to the dependency tree?

Share:
28,980

Related videos on Youtube

Kasper van den Berg
Author by

Kasper van den Berg

Programmer both professionally –I work at advitronic, we develop systems to monitor refrigeration systems for super markets– and as a hobby several projects. Unfortunately, I have a tendency to work at a level of abstraction that few understand. Occasionally I find myself at the limits of the language i'm working in. At work I use c# and javascript. In my spare time -when not playing with my daugther- I'm studying common-lisp and working on a few fletchling projects in that language. Previously I used c++-98, java, and several other languages.

Updated on July 09, 2022

Comments

  • Kasper van den Berg
    Kasper van den Berg almost 2 years

    Another instance of the NoSuchMethodError for the JUnit & Hamcrest combination. Offending code:

    assertThat(dirReader.document(0).getFields(), hasItem(
        new FeatureMatcher<IndexableField, String>(equalTo("Patisnummer"), "Field key", "Field key") {
            @Override
            protected String featureValueOf(IndexableField actual) {
                return actual.name();
            } } ));
    

    Commented lines 152–157 in IndexerTest.java (commit ac72ce)

    Causes a NoSuchMethodError (see http://db.tt/qkkkTE78 for complete output):

    java.lang.NoSuchMethodError: org.hamcrest.Matcher.describeMismatch(Ljava/lang/Object;Lorg/hamcrest/Description;)V
    at org.hamcrest.FeatureMatcher.matchesSafely(FeatureMatcher.java:43)
    at org.hamcrest.TypeSafeDiagnosingMatcher.matches(TypeSafeDiagnosingMatcher.java:55)
    at org.hamcrest.core.IsCollectionContaining.matchesSafely(IsCollectionContaining.java:25)
    at org.hamcrest.core.IsCollectionContaining.matchesSafely(IsCollectionContaining.java:14)
    at org.hamcrest.TypeSafeDiagnosingMatcher.matches(TypeSafeDiagnosingMatcher.java:55)
    at org.junit.Assert.assertThat(Assert.java:770)
    at org.junit.Assert.assertThat(Assert.java:736)
    at indexer.IndexerTest.testIndexContainsField(IndexerTest.java:152)
    

    The setup:

    • JUnit 4.11
    • Hamcrest 1.3
    • Using Maven's surefire plugin (version 2.14), which uses its JUnitCoreProvider
    • Java 7 (OpenJDK)
    • See pom (commit ac72ce)

    Background:

    A NoSuchMethodError is caused by (compiled) classes that call non existing methods. The specific case of describeMismatch and the JUnit + Hamcrest combination is often caused by an incompatibility between Hamcrest classes included in JUnit and versions of those classes in the Hamcrest library.

    Attempts to solve the NoSuchMethodError:

    • The pom contains an explicit dependency on Hamcrest-library 1.3, Hamcrest-core 1.3, and JUnit 4.11, (in that order) as suggested by Garrett Hall in answer to Getting "NoSuchMethodError: org.hamcrest.Matcher.describeMismatch" when running test in IntelliJ 10.5

    • According to the JUnit documentation the JUnit 4.11 Maven dependency does no longer include compiled Hamcrest classes, instead it has a dependency on Hamcrest-core 1.3; so the NoSuchMethodError should not occur.

    • Checking the dependency tree with mvn dependency:tree as suggested by Dan in answer to junit and hamcrest declaration shows the explicit dependencies on Hamcrest 1.3 and JUnit 4.11 and no other dependencies to those files (see http://db.tt/C2OfTDJB for the complete output).

    • In another test the NoSuchMethodError was avoided by using:

      assertThat(
          "Zylab detector not available",
          d.getDetectors(),
          hasItem(Matchers.<Detector>instanceOf(ZylabMetadataXmlDetector.class)));
      

      In lines 120–123 of IndexerTest.java (commit ac72ce) instead of the more obvious:

      assertThat(
          "Zylab detector not available",
          d.getDetectors(),
          hasItem(isA(ZylabMetadataDetector.class));
      

      I'm uncertain whether the explicit type parameter <Detector>, using instanceOf instead of isA, the explicit reference to Hamcrest's Matchers, or a combination of those avoided the NoSuchMethodException; after fiddling around and trying different things it worked.

    • Using explicit type parameters did not solve/avoid the error.

    • Using a class derived from BaseMatcher instead of FeatureMatcher did not solve/avoid the error.

    Ideas how fix the NoSuchMethodError?

  • Kasper van den Berg
    Kasper van den Berg about 11 years
    Thanks, I'm not (yet) aware of such a plugin, but your answer inspired an idea to combine Maven's dependency plugin, jar, and grep. And search for BaseMatcher in the classpath. A good startingpoint for monday.
  • Dion Truter
    Dion Truter about 10 years
    Thanks for the answer, I had the same problem and your solution worked for me.
  • Yauhen
    Yauhen almost 10 years
    Exclusions didn't help me, but the order of lib's helped: hamcrest dependency(library) should be before in Junit and/or Mockito dependencies
  • Yauhen
    Yauhen almost 10 years
  • Ulf Lindback
    Ulf Lindback over 9 years
    Note! You cannot use mockito-all since that has hamcrest (1.1) inside it, NOT as a dependcy. Instead, use mockito-core with teh hamcrest-core exclusion. You don't need to exclude hamcrest from junit 4.11 since that depends on hamcrest 1.3, only on earlier junit version.
  • ayahuasca
    ayahuasca about 8 years
    This worked for me. Mockito-all does appear to be the offending package. It helps to run "mvn dependency:tree -Dscope=test" to root out all inherited dependencies to mockito-all - if you are working on a large project, some imported modules may be using it without your knowledge.
  • HairOfTheDog
    HairOfTheDog almost 8 years
    FYI - You'll need to add a closing parenthesis to the very end of that Bash command
  • Kasper van den Berg
    Kasper van den Berg almost 8 years
    @HairOfTheDog added closing parenthesis.