Java "NoSuchMethodError" - PullRequest
       8

Java "NoSuchMethodError"

25 голосов
/ 12 сентября 2010

Я получаю:

NoSuchMethodError: com.foo.SomeService.doSmth()Z

Правильно ли я понимаю, что это 'Z' означает, что возвращаемый тип метода doSmth () является логическим? Если true, то такого рода метод действительно не существует, потому что этот метод возвращает некоторую коллекцию. Но с другой стороны, если я вызываю этот метод, я не присваиваю его возвращаемое значение какой-либо переменной. Я просто называю этот метод так:

service.doSmth();

Есть идеи, почему возникает эта ошибка? Все необходимые JAR-файлы существуют, и все другие методы этого класса, похоже, существуют.

Ответы [ 7 ]

24 голосов
/ 12 сентября 2010

Похоже, что метод существует в classpath во время компиляции, но не во время работы приложения.

Я не думаю, что возвращаемый тип является проблемой.Если бы это было, это не скомпилировало бы.Компилятор выдает ошибку, когда вызов метода неоднозначен, и это когда два метода отличаются только типом возвращаемого значения.

18 голосов
/ 12 сентября 2010

Обычно эта ошибка отлавливается компилятором; эта ошибка может возникнуть только во время выполнения, если определение класса несовместимо изменилось.

Короче говоря - файл класса / jar во время выполнения не тот, который вы использовали во время компиляции.

16 голосов
/ 12 сентября 2010

Вероятно, это разница между вашим classpath во время компиляции и вашим classpath во время выполнения.

Вот что происходит:

  • Код компилируетсяпуть к классу, который определяет метод doSmth(), возвращающий логическое значение.Байт-код относится к методу doSmth()Z.
  • Во время выполнения метод doSmth()Z не найден.Вместо этого найден метод, возвращающий коллекцию.

Чтобы исправить эту проблему, проверьте путь к классам (время компиляции).

4 голосов
/ 08 апреля 2013

Текущий ответ просто скажет вам, почему не удается.Обычно еще приятнее знать, как решить проблемы.Как уже упоминалось, проблема обычно заключается в том, что вы создали свою программу, но при ее запуске или экспорте библиотека не включается.Таким образом, решение ...

Если вы работаете, проверьте конфигурацию запуска Выберите вкладку «Выполнить» -> «Выполнить конфигурации» -> выберите конфигурацию, которую вы используете -> проверьте вкладку «Classpath» -> Убедитесь, что библиотекинужно там есть

Если вы экспортируете (например, файл war), следуйте этому Выберите проект -> Выбрать свойства -> Выбрать сборку развертывания -> Нажмите Добавить -> Выбрать записи пути сборки Java -> Выбрать библиотекивы хотите быть включенным в ваш экспортируемый файл (например, файл war)

В обоих случаях убедитесь, что библиотека, на которую вы ссылаетесь, включена.

Другими частыми проблемами этой ошибки не являютсяправильный тип параметров или видимости, но затем компилятор обнаружит ошибку перед запуском.В этом случае просто проверьте документацию на соответствие функции и видимости пакета и убедитесь, что библиотека находится в Java Build Path в свойствах вашего проекта.

3 голосов
/ 10 ноября 2015

Может быть, еще может кому-то помочь, но это исключение может произойти и в том случае, если у вас в classpath два класса в разных jar-файлах, которые имеют одинаковую точную сигнатуру, но у них нет одинаковых открытых методов.

Дляпример:

  • В файле mylibrary1.jar у вас есть класс com.mypackage.mysubpackage.MyClass с методом doSmth ()

  • В файле mylibrary2.У вас есть класс com.mypackage.mysubpackage.MyClass без метод doSmth ()

При поиске в классе загрузчик классов может найти первый mylibrary2.jar в зависимости отприоритет пути, но не удается найти метод для этого класса.

Убедитесь, что у вас нет одного и того же пакета + класс в двух разных файлах.

2 голосов
/ 27 января 2012

Я заметил, что эта проблема возникает при тестировании некоторых экспериментальных изменений в нескольких связанных проектах после их обновления из SVN в Eclipse.

В частности, я обновил все проекты из SVN и отменил файл .classpath вместо того, чтобы редактировать его вручную, чтобы упростить задачу.

Затем я заново добавил связанные проекты в путь, но забыл удалить связанные банки.Вот как проблема возникла для меня.

Таким образом, очевидно, что во время выполнения использовался файл jar, в то время как компилятор использовал файлы проекта.

0 голосов
/ 09 мая 2015

Другой способ, которым это может случиться, и его трудно найти:

Если сигнатура метода во внешнем jar-файле изменяется таким образом, что в IDE не обнаружено ошибок, поскольку он по-прежнему совместим с тем, как вы его называете, класс может не перекомпилироваться.

Если ваша сборка проверяет файлы на наличие изменений и только потом перекомпилирует их, класс может не перекомпилироваться во время процесса сборки.

Так что, когда вы запустите его, это может привести к этой проблеме. Несмотря на то, что у вас есть новый jar, ваш собственный код ожидает все еще старый, но никогда не жалуется.

Чтобы сделать это сложнее, от jvm зависит, сможет ли он справиться с такими случаями. Так что в худшем случае он работает на тестовом сервере, но не на работающей машине.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...