Ложный NoSuchMethodError

Получил NoSuchMethodError в одном из наших классов с помощью простого метода получения. Странно то, что мы можем отлаживать код и видеть, что ошибка возникает в отладчике (переходя через соответствующую строку), однако мы также можем использовать IDE (IntelliJ IDEA), чтобы увидеть, что метод существует.

Выполнение xxxx.getYYY() хорошо оценивается с помощью оценщика выражений IDE. И переходя xxxx.getClass().getMethods(), мы можем увидеть метод getYYY() в списке. Мы пытались очистить все встроенные файлы, выходные каталоги IDE, кеши IDE, перезагрузить компьютер и т. д., но ничего не помогает.

Я бы понял, что NoSuchMethodError произойдет, если мы скомпилируем что-то, но тогда во время выполнения будет найден другой Jar/класс. Но это не объясняет мне, почему во время выполнения при отладке рассматриваемой строки мы видим, что метод есть, но переход по строке вызывает исключение.

Пробовал воспроизводить на другой машине, но не воспроизводится.

Кто-нибудь знает, что здесь может происходить?


person Mike Q    schedule 22.06.2011    source источник
comment
у вас есть собственная иерархия загрузчиков классов?   -  person Suraj Chandran    schedule 22.06.2011
comment
Не могли бы вы отредактировать вопрос и добавить (полную) трассировку стека?   -  person Wivani    schedule 22.06.2011
comment
Что делает эта строка/метод, и уверены ли вы, что это не тот метод, который вызывает NoSuchMethodError?   -  person Kaj    schedule 22.06.2011
comment
Можете ли вы дать больше информации о настройке вашего проекта? Вы запускаете свое приложение через IntelliJ или из командной строки?   -  person Jens Hoffmann    schedule 22.06.2011
comment
@Suraj, не только стандартный загрузчик классов. Просто используя базовый Spring в качестве контейнера без каких-либо умных вещей.   -  person Mike Q    schedule 22.06.2011
comment
@Kaj, исключение указывает точный метод с подписью, поэтому довольно ясно, какой метод вызывает проблему.   -  person Mike Q    schedule 22.06.2011
comment
@Jens, на рассматриваемой машине мы запустили ее через IntelliJ, и она не удалась, И запустили нашу сборку ant и запустили ее из командной строки, та же проблема. Проверка точно такого же кода вне системы управления версиями на другой машине работает нормально.   -  person Mike Q    schedule 22.06.2011


Ответы (2)


Скорее всего, вы не используете те же версии кода в IntelliJ, что и редактируемые. Я часто сталкиваюсь с этой проблемой, когда множество проектов maven открыто одновременно с разными версиями в зависимости от того, что я редактирую. IntelliJ может запутаться (или я запутался в том, какую версию я на самом деле использую)

person Peter Lawrey    schedule 22.06.2011
comment
Да, это была моя первая мысль, но это не объясняет способность рефлексивно видеть метод во время выполнения. - person Mike Q; 22.06.2011
comment
Метод может немного отличаться, например. тип возвращаемого значения может быть другим. Для JVM важны все параметры и тип возвращаемого значения. - person Peter Lawrey; 22.06.2011
comment
@Питер. Это интересно. Обладает ли вызывающий объект полной информацией о вызывающем методе, включая типы параметров и тип возвращаемого значения? У меня сложилось впечатление, что JVM разрешается во время выполнения и выдает NoSuchMethodError, если значения параметров нельзя привести к целевому методу? - person Mike Q; 22.06.2011
comment
@Mike Q, это то, что делает компилятор. Если вы измените тип возвращаемого значения с long на int, вам придется перекомпилировать вызывающие программы, даже если вам не потребуется изменять код. - person Peter Lawrey; 22.06.2011
comment
@Peter, я думаю, ты был прав с типом возврата. В какой-то момент мы изменили его, чтобы возвращать Integer, а не int, и я думаю, что старая банка была поднята. Очень трудно обнаружить в отладчике эту небольшую разницу. - person Mike Q; 23.06.2011
comment
Согласен, поскольку Java не использует возвращаемый тип как часть подписи, а Class.getMethod(Class[]) тоже этого не делает, легко забыть, что JVM делает. - person Peter Lawrey; 23.06.2011
comment
Эта статья может показаться вам интересной. Он показывает, как вы можете перегрузить по возвращаемым типам в Java. vanillajava.blogspot.com/2011/ 02/ - person Peter Lawrey; 23.06.2011

NoSuchMethodError — в основном это происходит во время выполнения. Я столкнулся с этой ошибкой, причина была в несовместимости версий библиотек asm и cglib в моем пути к классам.

Библиотеки asm и cglib используются многими фреймворками, такими как hibernate, spring, hadoop, для манипулирования байт-кодом во время выполнения.

Загрузчик классов всегда ссылается на первую версию jar в пути к классам.

person LearningAboutTech    schedule 03.09.2015