web-dev-qa-db-ja.com

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 (commit ac72ce )のコメント行152–157

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
  • ハムクレスト1.3
  • JUnitCoreProviderを使用するMavenのsurefireプラグイン(バージョン2.14)を使用する
  • Java 7(OpenJDK)
  • pom (commit ac72ce )を参照してください

バックグラウンド:

NoSuchMethodError は、存在しないメソッドを呼び出す(コンパイルされた)クラスが原因です。 describeMismatchとJUnit + Hamcrestの組み合わせの特定のケースは、JUnitに含まれるHamcrestクラスとHamcrestライブラリ内のそれらのクラスのバージョン間の非互換性が原因であることがよくあります。

NoSuchMethodErrorの解決を試みます。

  • Pomには、 Garrett Hall in answer to-によって示唆されているように、Hamcrest-library 1.3、Hamcrest-core 1.3、およびJUnit 4.11への明示的な依存関係が含まれています(この順序で) IntelliJ 10.5でテストを実行するときに「NoSuchMethodError:org.hamcrest.Matcher.describeMismatch」を取得

  • JUnitのドキュメントによると、JUnit 4.11 Mavenの依存関係には、コンパイル済みのHamcrestクラスが含まれなくなり、代わりにHamcrest-core 1.3に依存しています。そのため、NoSuchMethodErrorは発生しません。

  • Dan in answer to junitおよびhamcrest宣言 で示唆されているように、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 (コミット ac72ce )の120〜123行目では、より明白なものではありません。

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

    明示的な型パラメーター<Detector>instanceOfの代わりにisAを使用するか、HamcrestのMatchersへの明示的な参照、またはそれらの組み合わせが使用されるかどうかはわかりませんNoSuchMethodException;いじっていろいろなことを試した後、うまくいきました。

  • 明示的な型パラメーターを使用しても、エラーは解決/回避されませんでした。

  • BaseMatcherの代わりにFeatureMatcherから派生したクラスを使用しても、エラーは解決/回避されませんでした。

NoSuchMethodErrorを修正する方法

42

このブログは私にとって同じ問題の解決に役立ちました。

https://tedvinke.wordpress.com/2013/12/17/mixing-junit-hamcrest-and-mockito-explaining-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>
26
Fred

David's tipおよび 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.CoreMatchers、およびorg.hamcrest.Matcherの独自のバージョンがあることがわかりました。

2

私のために働いたのは、依存関係を並べ替えることでした。 mockito、junitの代わりに、junit、mockitoを入れなければなりませんでした。

Mockito 1.9.5は、互換性がなく、問題を引き起こすhamcrest 1.1を使用します。

2
Arkady O

おそらく、これらの他のJARの1つには、古いバージョンのHamcrestのMatcherまたはBaseMatcherがあります。ここに JARのリスト があります。これには後者が含まれていますが、そのサイトがどれほど包括的かはわかりません。依存関係ツリーに類似したクラスを含むすべての依存関係を表示するMavenプラグインはありますか?

2
David Harkness

Eclipseを使用している場合、「Open Type」ツール(CTRL + SHIFT + T)を使用すると、問題のあるパッケージを見つけることができます。クラス名(例:説明)を検索するだけで、異なるJARからの同じクラスの複数の出現は危険信号です。

2
izilotti

Eclipseを使用している場合:私にとっては、Eclipse->プロジェクトプロパティ-> Javaビルドパスでmockito-all-1.9.5.jarを「Order and Export」リストの一番下に移動するとうまくいきました。そのすぐ上にjunit-4.11.jarがあり、その上にhamcrest-core-1.3.jarがあります

0
mrxjn

私はこれを解決しましたjar hell次のコードに関するGradleプロジェクトの問題:

    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'
0

ビルドツールとして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'
0
Arpit