Let’s say you’ve introduced JUnit and Hamcrest matchers to your project by adding the following to your pom.xml
<dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.11</version> </dependency> <dependency> <groupId>org.hamcrest</groupId> <artifactId>hamcrest-all</artifactId> <version>1.3</version> </dependency>
For the first time there’s a possibility when running a successful test it’s all peaches and fine, but when it fails you’ll be confronted with a
java.lang.NoSuchMethodError: org/hamcrest/Matcher.describeMismatch(Ljava/lang/Object;Lorg/hamcrest/Description;)V at org.hamcrest.collection.IsIterableContainingInOrder$MatchSeries.describeMismatch(IsIterableContainingInOrder.java:83) at org.hamcrest.collection.IsIterableContainingInOrder$MatchSeries.isMatched(IsIterableContainingInOrder.java:66) at org.hamcrest.collection.IsIterableContainingInOrder$MatchSeries.matches(IsIterableContainingInOrder.java:52) at org.hamcrest.collection.IsIterableContainingInOrder.matchesSafely(IsIterableContainingInOrder.java:25) at org.hamcrest.collection.IsIterableContainingInOrder.matchesSafely(IsIterableContainingInOrder.java:14) at org.hamcrest.TypeSafeDiagnosingMatcher.matches(TypeSafeDiagnosingMatcher.java:55) at org.hamcrest.MatcherAssert.assertThat(MatcherAssert.java:12) at org.junit.Assert.assertThat(Assert.java:865)
This could be due to the fact that JUnit itself brings along its own version of Hamcrest as a transitive dependency. Now if you would be using JUnit 4.11 it would depending on Hamcrest 1.3 already – see here. Getting above error would be weird – since the
describeMismatch method is present in
There seems to be an older version of
org.hamcrest.Matcher present on the classpath to which
If you run this from Eclipse or IntelliJ, there’s a high chance that the IDE uses its own version of JUnit instead of your Maven dependency. You should first rule that out by running
mvn clean install -Dtest<yourtest> outside your IDE .
If that still doesn’t work, check which dependencies are present on the classpath by running
mvn dependency:tree -Dscope=test which might give you some results like this:
[INFO] +- org.mockito:mockito-all:jar:1.9.5:test [INFO] +- com.tngtech.java:junit-dataprovider:jar:1.5.0:test [INFO] | \- com.google.code.findbugs:annotations:jar:2.0.1:test [INFO] \- org.hamcrest:hamcrest-all:jar:1.3:test [INFO] ------------------------------------------------------------------------
This lists all dependencies in the test scope – which possibly allows you to see whether or not another
Matcher class is brought in. If you have a lot of dependencies, what often might help is to look for the specifc class within the IDE.
If we we’re looking in Eclipse for the
Matcher classes we e.g. could see that there’s also one in
mockito-all-1.9.5.jar – see example screenshot above. Bugger! Seems
mockito-all is incompatible with JUnit 4.11 for backwards-compatibility reasons. The Hamcrest version 1.1
Matcher has been packaged within the dependency, so we can not exclude it.
Luckily for us, Mockito allows to us to use a mockito-core dependency instead of mockito-all. Running a dependency check (with dependency:tree or online) shows us it depends on
[INFO] +- org.mockito:mockito-core:jar:1.9.5:test [INFO] | \- org.hamcrest:hamcrest-core:jar:1.1:test
We can exclude it in the
pom.xml and – no more
NoSuchMethodError. Here’s the final combination of dependencies in our case:
<dependency> <groupId>org.mockito</groupId> <artifactId>mockito-core</artifactId> <version>1.9.5</version> <exclusions> <exclusion> <artifactId>hamcrest-core</artifactId> <groupId>org.hamcrest</groupId> </exclusion> </exclusions> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.11</version> <exclusions> <exclusion> <artifactId>hamcrest-core</artifactId> <groupId>org.hamcrest</groupId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.hamcrest</groupId> <artifactId>hamcrest-all</artifactId> <version>1.3</version> </dependency>
Featured image on top of this post courtesy of the The Junit / Green Lantern Oath.