java.lang.NoSuchMethodError, когда метод определенно существует - PullRequest
6 голосов
/ 17 ноября 2011

У меня есть веб-приложение на основе среды Spring, созданное в SpringSource Tool Suite («STS»), и локальная копия Apache Tomcat.У нас также есть внутренний рабочий сервер, на котором снова запущен Tomcat.

Когда я запускаю приложение на своем компьютере разработчика и выполняю определенное действие в веб-приложении, все работает правильно.Однако, когда я развертываю веб-приложение в Tomcat на сервере (через файл war, созданный maven) и повторяю вышеупомянутые конкретные действия, у меня появляется неожиданное поведение.Когда я проверил файл журнала сервера tomcat, я обнаружил, что ...

2011-11-16 19:36:45,090 [http-8280-Processor1] ERROR [attachments]  invoke - Servlet.service() for servlet attachments threw exception java.lang.NoSuchMethodError: net.wmfs.coalesce.aa.dao.MediaDao.updateAlfrescoNodeRef(Ljava/lang/Long;Ljava/lang/String;)V
at net.wmfs.coalesce.aa.service.impl.MediaServiceImpl.doFileUpload(MediaServiceImpl.java:102)
at net.wmfs.coalesce.aa.servlet.MediaServlet.doFileUpload(MediaServlet.java:83)
at net.wmfs.coalesce.aa.servlet.MediaServlet.doPost(MediaServlet.java:55)

Теперь метод updateAlfrescoNodeRef определенно существует в классе MediaDao - иначе мой код не будет компилироваться в STS ...

package net.wmfs.coalesce.aa.dao;

public class MediaDao extends JdbcDaoSupport {

    public void updateAlfrescoNodeRef(final Long recordId, final String nodeRef) {
        // java code
    }
}

Как видите, подпись метода правильная.

Я подозревал, что, возможно, возникла проблема, когда maven создал файл war, поэтому я извлек содержимое файла war.В папке WEB-INF / lib я нашел файл jar, в котором содержится класс MediaDao, и извлек его содержимое.Затем я сделал ...

cat ./MediaDao.class

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

Конфигурация bean-компонента в XML-файлах среды Spring определенно правильная, иначе код не запустится, когда я выполню его на своем компьютере разработчика.

Googling предложил конфликт библиотеки на сервере, но все упомянутые классы - MediaServlet, MediaServiceImpl, MediaDao - находятся в основном проекте (тот, в котором есть папка WEB-INF).Хотя возможно, что на сервере может быть несколько копий зависимостей, определенно есть только одна копия основного проекта.

У кого-нибудь есть идеи, почему это происходит?

Ответы [ 3 ]

9 голосов
/ 18 ноября 2011

Проблема теперь решена. Спасибо всем за вашу помощь.

Оказывается, у основного проекта была зависимость, у которой был другой класс MediaDao, точно такой же путь к пакету. Кто-то в основном скопировал класс в эту зависимость (как ресурс библиотеки, чтобы многие проекты могли использовать его без указания основного проекта в качестве зависимости). Однако этот кто-то не удалил класс в основном проекте.

Итак, когда я изменил класс в основном проекте (я добавил метод updateAlfrescoNodeRef) и запустил приложение в STS на моей машине, Tomcat использовал версию класса в основном проекте, а не в библиотека, потому что проект библиотеки был закрыт. Однако когда приложение было развернуто на сервере, похоже, что вместо него использовалась версия класса в библиотеке (в которой, конечно, не было метода updateAlfrescoNodeRef).

Совет эксперта, если вы когда-нибудь окажетесь в подобной ситуации: в STS нажмите CTRL + SHIFT + T, чтобы открыть диалоговое окно «Открыть тип», и введите имя проблемного класса, чтобы увидеть список проектов, имеющих класс с таким именем.

1 голос
/ 09 ноября 2016

Если ошибка произошла в Android Studio, это также может быть ошибка Instant Run.В этом случае: File -> Invalidate Caches / Restart.Это решило мою проблему

0 голосов
/ 17 ноября 2011

Если вы используете Tomcat 6+, найдите в ~ tomcat / lib конфликтующие классы и файлы jar. В Tomcat 5 ищите ~ tomcat / common / classes, ~ tomcat / common / lib, ~ tomcat / shared / classes и ~ tomcat / shared / lib.

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