1. Обзор
В этом уроке мы рассмотрим java.lang.NoSuchMethodError и некоторые способы справиться с этим.
2. noSuchMethod error
Как следует из названия, ошибка noSuchMethod возникает, когда конкретный метод не найден . Этот метод может быть либо методом экземпляра, либо статическим методом.
В большинстве случаев мы можем поймать эту ошибку во время компиляции. Следовательно, , это не большая проблема. Однако иногда он может быть брошен во время выполнения , тогда найти его становится немного сложно. Согласно документации Oracle , эта ошибка может возникнуть во время выполнения, если класс был изменен несовместимо.
Следовательно, мы можем столкнуться с этой ошибкой в следующих случаях. Во-первых, если мы сделаем только частичную перекомпиляцию нашего кода. Во-вторых, если есть несовместимость версий с зависимостями в нашем приложении, такими как внешние банки.
Обратите внимание, что дерево наследования noSuchMethod/| включает в себя IncompatibleClassChangeError и LinkageError . Эти ошибки связаны с несовместимым изменением класса после компиляции.
3. Пример ошибки noSuchMethod
Давайте рассмотрим эту ошибку в действии на примере. Для этого мы создадим два класса. Во-первых, это Специальное предложение сегодня в котором будут перечислены специальные предложения на день в ресторане:
public class SpecialToday { private static String desert = "Chocolate Cake"; public static String getDesert() { return desert; } }
Второй класс Главное меню методы вызовов из Специальные предложения сегодня:
public class MainMenu { public static void main(String[] args) { System.out.println("Today's Specials: " + getSpecials()); } public static String getSpecials() { return SpecialToday.getDesert(); } }
Здесь выход будет:
Today's Specials: Chocolate Cake
Затем мы удалим метод get Desert() в Special Today и перекомпилируем только этот обновленный класс. На этот раз, когда мы запускаем наше Главное меню, мы замечаем следующую ошибку во время выполнения:
Exception in thread "main" java.lang.NoSuchMethodError: SpecialToday.getDesert()Ljava/lang/String;
4. Как справиться с NoSuchMethodError
Теперь давайте посмотрим, как мы сможем справиться с этим. Для приведенного выше кода давайте сделаем полную чистую компиляцию, включая оба класса. Мы заметим, что ошибка будет обнаружена во время компиляции. Если мы используем IDE, такую как Eclipse , она будет обнаружена еще раньше, как только мы обновим Специальные предложения сегодня .
Следовательно, если мы столкнемся с этой ошибкой в наших приложениях, в качестве первого шага мы сделаем полную чистую компиляцию. С помощью maven мы запустим команду mvn clean install .
Иногда проблема заключается во внешних зависимостях нашего приложения. В этом случае мы сначала проверим порядок банок в пути сборки, извлеченном загрузчиком classpath. И мы отследим и обновим несогласованную банку.
Однако, если мы все еще сталкиваемся с этой ошибкой во время выполнения, нам придется копать глубже. Мы должны убедиться, что во время компиляции и во время выполнения классы и банки имеют одинаковые версии . Для этого мы можем запустить приложение с параметром-verbose: class , чтобы проверить загруженные классы. Мы можем выполнить команду следующим образом:
$ java -verbose:class com.baeldung.exceptions.nosuchmethoderror.MainMenu [0.014s][info][class,load] opened: /usr/lib/jvm/java-11-openjdk-amd64/lib/modules [0.015s][info][class,load] opened: /usr/share/java/java-atk-wrapper.jar [0.028s][info][class,load] java.lang.Object source: shared objects file [0.028s][info][class,load] java.io.Serializable source: shared objects file
Используя эту информацию обо всех классах, загружаемых в отдельные банки, во время выполнения, мы можем проследить несовместимую зависимость.
Мы также должны убедиться, что в двух или более банках нет повторяющихся классов . В большинстве случаев maven поможет напрямую контролировать конфликтующие зависимости|/. Кроме того, мы можем запустить команду mvn dependency: tree , чтобы получить дерево зависимостей нашего проекта следующим образом:
$ mvn dependency:tree [INFO] Scanning for projects... [INFO] [INFO] -------------< com.baeldung.exceptions:nosuchmethoderror >-------------- [INFO] Building nosuchmethoderror 0.0.1-SNAPSHOT [INFO] --------------------------------[ jar ]--------------------------------- [INFO] [INFO] --- maven-dependency-plugin:2.8:tree (default-cli) @ nosuchmethoderror --- [INFO] com.baeldung.exceptions:nosuchmethoderror:jar:0.0.1-SNAPSHOT [INFO] \- org.junit:junit-bom:pom:5.7.0-M1:compile
Мы можем проверить библиотеки и их версии в списке, сгенерированном этой командой. Кроме того, мы также можем управлять зависимостями с помощью тегов maven. Используя тег <исключения>, мы можем исключить проблемную зависимость. Используя тег <необязательно>, мы можем предотвратить включение нежелательных зависимостей в jar или war.
5. Заключение
В этой статье мы обратились к NoSuchMethodError . Мы обсудили причину этой ошибки, а также способы ее устранения. Для получения более подробной информации о том, как правильно обрабатывать ошибки, пожалуйста, обратитесь к нашей статье о ловле ошибок Java .
Как всегда, код, представленный в этой статье, доступен на GitHub.