【问题标题】:NoSuchMethodError with Hamcrest 1.3 & JUnit 4.11Hamcrest 1.3 和 JUnit 4.11 的 NoSuchMethodError
【发布时间】:2013-04-05 11:40:18
【问题描述】:

NoSuchMethodError 的另一个实例,用于 JUnit 和 Hamcrest 组合。 违规代码:

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 行(提交 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(提交ac72ce

背景:

NoSuchMethodError 是由调用不存在方法的(编译的)类引起的。 describeMismatch 和 JUnit + Hamcrest 组合的具体情况通常是由 JUnit 中包含的 Hamcrest 类与 Hamcrest 库中这些类的版本之间的不兼容引起的。

尝试解决 NoSuchMethodError:

  • 按照Garrett HallanswerGetting "NoSuchMethodError: org.hamcrest.Matcher.describeMismatch" when running test in IntelliJ 10.5 中的建议,pom 包含对 Hamcrest-library 1.3、Hamcrest-core 1.3 和 JUnit 4.11 的显式依赖(按此顺序)

  • 根据 JUnit 文档,JUnit 4.11 Maven 依赖不再包括已编译的 Hamcrest 类,而是依赖于 Hamcrest-core 1.3;所以NoSuchMethodError 不应该出现。

  • 按照Dananswerjunit and hamcrest declaration 中的建议,使用mvn dependency:tree 检查依赖关系树显示了对Hamcrest 1.3 和JUnit 4.11 的显式依赖关系,并且对这些文件没有其他依赖关系(参见http://db.tt/C2OfTDJB完整的输出)。

  • 在另一个测试中,NoSuchMethodError 被使用:

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

    IndexerTest.java 的第 120–123 行(提交 ac72ce) 而不是更明显的:

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

    我不确定是显式类型参数&lt;Detector&gt;、使用instanceOf而不是isA、显式引用Hamcrest的Matchers,还是避免使用NoSuchMethodException的组合;在摆弄并尝试了不同的东西之后,它起作用了。

  • 使用显式类型参数不能解决/避免错误。

  • 使用派生自 BaseMatcher 的类而不是 FeatureMatcher 无法解决/避免错误。

想法如何修复NoSuchMethodError

【问题讨论】:

    标签: maven junit junit4 maven-surefire-plugin hamcrest


    【解决方案1】:

    这个博客帮助我解决了同样的问题:

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

    在Mockito和Junit的依赖中,作者添加了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>
    

    【讨论】:

    • 感谢您的回答,我遇到了同样的问题,您的解决方案对我有用。
    • 排除对我没有帮助,但 lib 的顺序有帮助:hamcrest 依赖项(库)应该在 Junit 和/或 Mockito 依赖项之前
    • 这个stackoverflow.com/questions/7869711/… 似乎可以提供帮助
    • 注意!你不能使用 mockito-all,因为它里面有 hamcrest (1.1),而不是依赖。相反,使用带有 hamcrest-core 排除的 mockito-core。您不需要从 junit 4.11 中排除 hamcrest,因为这取决于 hamcrest 1.3,仅取决于早期的 junit 版本。
    • 这对我有用。 Mockito-all 似乎确实是有问题的软件包。它有助于运行“mvn dependency:tree -Dscope=test”来根除所有继承的依赖于 mockito-all - 如果您正在处理一个大型项目,一些导入的模块可能会在您不知情的情况下使用它。
    【解决方案2】:

    也许其他 JAR 之一具有 Hamcrest 的 MatcherBaseMatcher 的旧版本。这是一个list of JARs,其中包括后者,尽管我不知道该网站的全面性。是否有一个 Maven 插件可以显示所有依赖关系,其中包含一个类似于依赖关系树的类?

    【讨论】:

    • 谢谢,我(还)不知道这样的插件,但你的回答激发了一个想法,将 Maven 的依赖插件、jar 和 grep 结合起来。并在类路径中搜索 BaseMatcher。星期一的一个很好的起点。
    【解决方案3】:

    如果您使用的是 Eclipse,“打开类型”工具 (CTRL+SHIFT+T) 可以帮助您找到有问题的包。只需搜索类名(例如,Description),来自不同 JAR 的同一类多次出现是危险信号。

    【讨论】:

      【解决方案4】:

      对我有用的是重新排序依赖项。 而不是去模仿,junit, 我不得不把junit,mockito。

      Mockito 1.9.5 使用不兼容的 hamcrest 1.1 并导致问题。

      【讨论】:

        【解决方案5】:

        使用 David's tip 和 How do I split a string on a delimiter in Bash? 生成以下 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.BaseMatcherorg.hamcrest.CoreMatchersorg.hamcrest.Matcher版本。

        【讨论】:

        • 仅供参考 - 您需要在该 Bash 命令的最后添加一个右括号
        • @HairOfTheDog 添加了右括号。
        【解决方案6】:

        对于以Gradle 作为构建工具的项目:

        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'
        

        【讨论】:

          【解决方案7】:

          如果您使用的是 Eclipse: 对我来说,在 eclipse-> 项目属性-> Java build Path 将 mockito-all-1.9.5.jar 移动到“Order and Export”列表的底部就可以了。就在上面我有 junit-4.11.jar 和上面那个 hamcrest-core-1.3.jar

          【讨论】:

            【解决方案8】:

            我用下面的代码在我的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'
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2014-06-03
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多