Kasper van den Berg
Kasper van den Berg

Reputation: 9526

NoSuchMethodError with Hamcrest 1.3 & JUnit 4.11

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:

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:

Ideas how fix the NoSuchMethodError?

Upvotes: 43

Views: 30212

Answers (8)

Arpit Aggarwal
Arpit Aggarwal

Reputation: 29276

For a project with Gradle as a build tool:

testCompile("junit:junit:4.11") {
     exclude group: 'org.hamcrest', module: 'hamcrest-core'
     exclude group: 'org.hamcrest', module: 'hamcrest-library' 
}
testCompile group: 'org.hamcrest', name: 'hamcrest-core', version: '1.3'
testCompile group: 'org.hamcrest', name: 'hamcrest-library', version: '1.3'

Upvotes: 1

John John
John John

Reputation: 4575

I solved this jar hell problem in my Gradle project with the code below:

    testCompile (group: 'junit', name: 'junit', version: '4+') {
        exclude group: 'org.hamcrest'
    }
    testCompile ('org.mockito:mockito-core:1+') {
        exclude group: 'org.hamcrest'
    }
    testCompile 'org.hamcrest:java-hamcrest:2.0.0.0'

Upvotes: 0

Kasper van den Berg
Kasper van den Berg

Reputation: 9526

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.

Upvotes: 2

mrxjn
mrxjn

Reputation: 53

If you are using Eclipse: For me, in eclipse-> project properties->Java build Path moving mockito-all-1.9.5.jar to the bottom of the 'Order and Export' list did the trick. Just above that I have junit-4.11.jar and above that hamcrest-core-1.3.jar

Upvotes: 0

Arkady O
Arkady O

Reputation: 21

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.

Upvotes: 2

Fred
Fred

Reputation: 286

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>

Upvotes: 27

izilotti
izilotti

Reputation: 4927

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.

Upvotes: 2

David Harkness
David Harkness

Reputation: 36542

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?

Upvotes: 2

Related Questions