Java "NoSuchMethodError"
Я получаю:
NoSuchMethodError: com.foo.SomeService.doSmth()Z
Я правильно понимаю, что этот 'Z'
означает, что возвращаемый тип doSmth() является логическим? Если true, то такого метода действительно не существует, потому что этот метод возвращает некоторую коллекцию. Но, с другой стороны, если я вызываю этот метод, я не назначаю его возвращаемое значение для любой переменной. Я просто вызываю этот метод следующим образом:
service.doSmth();
Любые идеи, почему эта ошибка возникает? Все необходимые файлы JAR существуют, и все остальные методы из этого класса, похоже, существуют.
Ответы
Ответ 1
Похоже, что метод существует в пути к классам во время компиляции, но не во время запуска вашего приложения.
Я не думаю, что тип возврата - проблема. Если бы это было так, это не скомпилировалось бы. Компилятор выдает ошибку, когда вызов метода неоднозначен, и это происходит, когда два метода отличаются только возвращаемым типом.
Ответ 2
Обычно эта ошибка улавливается компилятором; эта ошибка может возникнуть только во время выполнения, если определение класса несовместимо изменилось.
Вкратце - файл класса /jar во время выполнения - это не то же самое, что вы использовали во время компиляции.
Ответ 3
Это, вероятно, разница между вашим пути времени компиляции и вашим путём класса времени выполнения.
Вот что происходит:
- Код компилируется с помощью пути класса, который определяет метод
doSmth()
, возвращающий логическое значение. Байт-код относится к методу doSmth()Z
.
- Во время выполнения метод
doSmth()Z
не найден. Вместо этого найден метод, возвращающий коллекцию.
Чтобы исправить эту проблему, проверьте путь к классу (время компиляции).
Ответ 4
В текущем ответе просто скажу вам, почему происходит сбой. Обычно даже лучше узнать, как исправить проблемы. Как уже упоминалось, обычно проблема заключается в том, что вы создали свою программу, но при ее запуске или ее экспорте библиотека не включена. Таким образом, решение...
Если вы работаете, проверьте конфигурацию запуска
Выберите вкладку "Выполнить" → "Выполнить конфигурации" → Выберите конфигурацию, в которой вы работаете, → "Проверить вкладку" Класс "- > Убедитесь, что библиотеки, которые вам нужны,
Если вы экспортируете (например, файл войны), выполните следующие действия:
Выберите проект → Выбрать свойства → Выбрать сборку развертывания → Нажмите Добавить → Выбрать записи пути Java Build → Выберите библиотеки, которые вы хотите включить в экспортированный файл (например, военный файл)
В обоих случаях убедитесь, что библиотека, на которую вы ссылаетесь, включена.
Другими частыми проблемами для этой ошибки являются неправильный тип параметров или видимость, но затем компилятор обнаружит ошибку перед запуском. В этом случае просто проверьте документацию в соответствии с видимостью функции и пакета и убедитесь, что библиотека найдена в Java Build Path в ваших свойствах проекта.
Ответ 5
Я заметил эту проблему при тестировании некоторых экспериментальных изменений в нескольких связанных проектах после обновления их из SVN в Eclipse.
В частности, я обновил все проекты из SVN и вернул файл .classpath, а не редактировал его вручную, чтобы все было просто.
Затем я снова добавил связанные проекты к пути, но забыл удалить связанные банки. Так возникла проблема для меня.
Таким образом, очевидно, что время выполнения использовало файл jar, в то время как компилятор использовал файлы проекта.
Ответ 6
Может быть, все-таки может помочь кто-то, но это исключение может произойти и тогда, когда у вас есть на пути к классу два класса в разных файлах jar, которые имеют одинаковую точную подпись, но у них нет одинаковых общедоступных методов.
Например:
При поиске класса загрузчик классов может найти первый mylibrary2.jar в зависимости от приоритета пути, но не может найти метод в этом классе.
Убедитесь, что у вас нет одного класса пакетов + в двух разных файлах.
Ответ 7
Другим способом это может случиться и трудно найти:
Если подпись метода во внешней банке изменяется так, что в среде IDE отсутствует ошибка, поскольку она по-прежнему совместима с тем, как вы ее называете, класс не может быть повторно скомпилирован.
Если ваша сборка проверяет файлы на наличие изменений и только затем перекомпилирует их, класс не может быть перекомпилирован в процессе сборки.
Поэтому, когда вы его запускаете, это может привести к этой проблеме. Хотя у вас есть новая банка, ваш собственный код ожидает еще старого, но никогда не жалуется.
Чтобы сделать это сложнее, это зависит от jvm, если он может обрабатывать такие случаи. Так что в худшем случае он работает на тестовом сервере, но не на реальном компьютере.