使用Hamcrest 1.3和JUnit 4.11的NoSuchMethodError
另一个JUnit&Hamcrest组合的NoSuchMethodError
实例。 出错代码:
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(); } } ));
IndexerTest.java中的注释行152-157(commit ac72ce )
导致NoSuchMethodError(请参阅http://db.tt/qkkkTE78获取完整的输出):
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)
设置:
- JUnit 4.11
- Hamcrest 1.3
- 使用Maven的surefire插件(版本2.14),它使用了JUnitCoreProvider
- Java 7(OpenJDK)
- 看到pom (commit ac72ce )
背景:
NoSuchMethodError
是由调用非现有方法的(编译)类引起的。 describeMismatch
和JUnit + Hamcrest组合的具体情况通常是由JUnit中包含的Hamcrest类与Hamcrest类库中这些类的版本之间的不兼容造成的。
尝试解决NoSuchMethodError:
-
pom包含Hamrerest-Library 1.3,Hamcrest-core 1.3和JUnit 4.11的显式依赖,正如Garrett Hall在回答 在运行testing时得到“NoSuchMethodError:org.hamcrest.Matcher.describeMismatch” (按照该顺序) IntelliJ 10.5
-
根据JUnit文档,JUnit 4.11 Maven依赖不再包含已编译的Hamcrest类,而是依赖于Hamcrest核心1.3; 所以
NoSuchMethodError
不应该发生。 -
使用
mvn dependency:tree
检查依赖关系树mvn dependency:tree
Dan在回答 junit和hamcrest声明时提供的mvn dependency:tree
显示了对Hamcrest 1.3和JUnit 4.11的显式依赖关系,而对这些文件没有其他依赖关系(请参阅http://db.tt/C2OfTDJB完成输出)。 -
在另一个testing中,使用下面的方法避免了
NoSuchMethodError
:assertThat( "Zylab detector not available", d.getDetectors(), hasItem(Matchers.<Detector>instanceOf(ZylabMetadataXmlDetector.class)));
在IndexerTest.java的第120-123 行 (commit ac72ce )而不是更明显的:
assertThat( "Zylab detector not available", d.getDetectors(), hasItem(isA(ZylabMetadataDetector.class));
我不确定是否显式types参数
<Detector>
,使用instanceOf
而不是isA
,显式引用Hamcrest的Matchers
,或者避免了NoSuchMethodException
的组合; 经过摆弄,尝试不同的事情。 -
使用显式types参数不能解决/避免错误。
-
使用派生自
BaseMatcher
而不是FeatureMatcher
的类没有解决/避免错误。
想法如何修复NoSuchMethodError
?
这个博客帮助我解决了同样的问题:
在Mockito和Junit的依赖关系中,作者增加了排除:
<dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.11</version> <exclusions> <exclusion> <artifactId>hamcrest-core</artifactId> <groupId>org.hamcrest</groupId> </exclusion> </exclusions> </dependency>
也许这些其他JAR中有一个是Hamcrest的Matcher
或BaseMatcher
老版本。 下面是包含后者的JAR列表 ,但我不知道该网站有多全面。 有没有一个Maven插件,它会告诉你所有的依赖关系,包括类依赖树的类?
如果您使用Eclipse,“打开types”工具(CTRL + SHIFT + T)可以帮助您find有问题的软件包。 只要search类名(例如Description),来自不同JAR的同一类的多次出现就是红旗。
对我有用的是重新sorting依赖关系。 而不是去mockito,junit,我必须把junit,mockito。
Mockito 1.9.5使用hamcrest 1.1,这是不兼容的,导致问题。
使用David的技巧,以及如何在Bash中的分隔符上分割string? 导致下面的bash脚本:
( IFS=":"; for i in `mvn dependency:build-classpath | grep -v '\[INFO\]'`; do jar tf $i | awk "{print \"$i\\t\" \$1}"; done | grep Matcher )
(在线http://www.kaspervandenberg.net/2013/scripts/findDependencyClass.sh )
其中发现依赖JGlobus-Core-2.0.4
有它自己的版本的org.hamcrest.BaseMatcher
, org.hamcrest.CoreMatchers
和org.hamcrest.Matcher
。
如果你正在使用Eclipse:对于我来说,在eclipse-> project properties-> Java build Path将mockito-all-1.9.5.jar移动到“Order and Export”列表的底部。 刚刚上面,我有junit-4.11.jar和以上那hamcrest-core-1.3.jar
我用下面的代码在我的Gradle
项目中解决了这个jar hell
问题:
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'
对于使用Gradle
作为构build工具的项目:
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'