Подтвердить что ты не робот

NoSuchMethodError с Hamcrest 1.3 и JUnit 4.11

Другой экземпляр 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();
        } } ));

Прокомментированные строки 152-157 в IndexerTest.java (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)

История:

A NoSuchMethodError вызвано (скомпилированными) классами, которые вызывают не существующие методы. Конкретный случай describeMismatch и комбинация JUnit + Hamcrest часто вызваны несовместимостью между классами Hamcrest, включенными в JUnit, и версиями этих классов в библиотеке Hamcrest.

Попытки решить проблему NoSuchMethodError:

  • В pom содержится явная зависимость от Hamcrest-библиотеки 1.3, Hamcrest-core 1.3 и JUnit 4.11 (в указанном порядке), как предложено Garrett Hall в ответить на Получение "NoSuchMethodError: org.hamcrest.Matcher.describeMismatch" при запуске теста в IntelliJ 10.5

  • Согласно документации JUnit, зависимость JNnit 4.11 Maven больше не включает скомпилированные классы Hamcrest, вместо этого она имеет зависимость от Hamcrest-core 1.3; поэтому NoSuchMethodError не должен появляться.

  • Проверка дерева зависимостей с mvn dependency:tree, как это было предложено Dan в to junit и hamcrest объявление показывает явные зависимости от Hamcrest 1.3 и JUnit 4.11 и никаких других зависимостей от этих файлов (см. http://db.tt/C2OfTDJB для полного вывода).

  • В другом тесте NoSuchMethodError было исключено использование:

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

    В строках 120-123 IndexerTest.java (commit ac72ce) вместо более очевидного:

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

    Я не уверен, что явный тип параметра <Detector>, используя instanceOf вместо isA, явную ссылку на Hamcrest Matchers или комбинацию тех, которые избегают NoSuchMethodException; после возиться и пробовать разные вещи, с которыми он работал.

  • Использование явных параметров типа не решило/не устранило ошибку.

  • Использование класса, полученного из BaseMatcher вместо FeatureMatcher, не решило/не устранило ошибку.

Идеи, как исправить NoSuchMethodError?

4b9b3361

Ответ 1

Этот блог помог мне решить ту же проблему:

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>

Ответ 2

Возможно, один из этих JAR имеет более ранние версии Hamcrest Matcher или BaseMatcher. Здесь список JARs, который включает последний, хотя я понятия не имею, насколько всеобъемлющим является этот сайт. Есть ли плагин Maven, который покажет вам все зависимости, которые включают класс, похожий на дерево зависимостей?

Ответ 3

Использование подсказки Дэвида и Как разделить строку на разделителе в Bash? в следующем bash script:

( 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.

Ответ 4

Если вы используете Eclipse, инструмент "Открыть тип" (CTRL + SHIFT + T) может помочь вам найти проблемный пакет. Просто найдите имя класса (например, описание), несколько вхождений одного и того же класса из разных JAR - это красные флаги.

Ответ 5

Что для меня работало, это переупорядочивать зависимости. Вместо того, чтобы идти mockito, junit, Мне пришлось положить junit, mockito.

Mockito 1.9.5 использует hamcrest 1.1, который несовместим и вызывает проблемы.

Ответ 6

Если вы используете Eclipse: Для меня, в eclipse- > свойствах проекта- > Java build Path перемещение mockito-all-1.9.5.jar в нижней части списка "Order and Export" сделал трюк. Чуть выше у меня есть junit-4.11.jar и выше этого hamcrest-core-1.3.jar

Ответ 7

Я решил эту проблему 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'

Ответ 8

Для проекта с 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'