Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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:

  • 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?

like image 816
Kasper van den Berg Avatar asked Apr 05 '13 11:04

Kasper van den Berg


People also ask

What is hamcrest core 1.3 jar?

hamcrest-core. jar : This was the core API to be used by third-party framework providers. This includes a foundation set of matcher implementations for common operations. This library was used as a dependency for many third-party libraries, including JUnit 4.

What is hamcrest used for?

Hamcrest is a framework that assists writing software tests in the Java programming language. It supports creating customized assertion matchers ('Hamcrest' is an anagram of 'matchers'), allowing match rules to be defined declaratively. These matchers have uses in unit testing frameworks such as JUnit and jMock.

What is hamcrest in API?

Hamcrest is a framework for writing matcher objects allowing 'match' rules to be defined declaratively. There are a number of situations where matchers are invaluable, such as UI validation or data filtering, but it is in the area of writing flexible tests that matchers are most commonly used.


2 Answers

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> 
like image 92
Fred Avatar answered Sep 29 '22 09:09

Fred


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?

like image 23
David Harkness Avatar answered Sep 29 '22 07:09

David Harkness