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
?
Ответы
Ответ 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'