NoSuchMethodError - Вызов класса / метода из класса в том же пакете
Мы интегрируем внутреннюю структуру в наше веблогическое приложение и сталкиваемся с проблемами развертывания.
Используемые технологии
- Приложение Weblogic 10.3.6
- Весна 3.0
- Maven 2
- Затмение J2EE
Эта проблема
При запуске приложения weblogic мы получаем следующее NoSuchMethodError при инициализации одного из компонентов. Эта ошибка возникает при вызове классов в jar org.joda.time (2.0).
Caused By: java.lang.NoSuchMethodError: org.joda.time.DateTimeZone.convertLocalToUTC(JZ)J
at org.joda.time.LocalDate.toDateTimeAtStartOfDay(LocalDate.java:715)
at org.joda.time.LocalDate.toDateTimeAtStartOfDay(LocalDate.java:690)
. . . excluded . . .
Вещи, которые мы попробовали
После поиска в Google "NoSuchMethodError spring" многие проблемы кажутся несовместимыми версиями Spring. После печати дерева зависимостей единственной используемой версией Spring является 3.0.
Поиск в Google "NoSuchMethodError" обычно давал адские решения JAR.
Несколько версий одной и той же зависимости. После некоторого управления зависимостями maven используется только joda-time jar 2.0. Кроме того, местный репозиторий был очищен от ненужных банок.
В.war / runtime могут отсутствовать правильные файлы jar, включенные в каталог lib. Посмотрев в каталог WEB_INF/lib, единственный joda-time jar - это версия 2.0, которая содержит все соответствующие файлы классов
Одна загадочная вещь заключается в том, что DateTimeZone.convertLocalToUTC(JZ)J был частью проекта org.joda.time начиная с 1.0, поэтому даже если у нас есть несовместимые версии, метод все равно должен быть найден, особенно если класс и пакет можно найти.
Наконец, в проекте нет других классов DateTimeZone (ctrl+shift+T search в eclipse), поэтому я не понимаю, какой класс загружается, если класс org.joda.DateTimeZone не загружается.
Вопросы:
- Может кто-нибудь объяснить, почему метод не может быть найден?
- Есть ли еще места, чтобы проверить наличие существующих или конфликтующих банок?
- Есть ли способ проверить класс DateTimeZone, который класс LocalDate использует во время выполнения с помощью отладки Eclipse?
2 ответа
Вот некоторые интересные чтения:
Элемент предпочитаемого веб-инф-класса
Дескриптор развертывания веб-приложения weblogic.xml содержит элемент (подэлемент элемента). По умолчанию этот элемент имеет значение False. Установка этого элемента в True подрывает модель делегирования загрузчика классов, так что определения классов из веб-приложения загружаются в предпочтение определениям классов в загрузчиках классов более высокого уровня. Это позволяет веб-приложению использовать собственную версию стороннего класса, который также может быть частью WebLogic Server. См. "Weblogic.xml Элементы дескриптора развертывания".
взяты из: http://docs.oracle.com/cd/E15051_01/wls/docs103/programming/classloading.html
Другие советы по устранению неполадок:
Вы можете попробовать: -verbose:class и проверить журналы вашего управляемого сервера, чтобы проверить, правильно ли загружается класс.
Эффективный способ подтвердить, какой навязчивый jar-файл может быть загружен, - это запустить whereis.jsp в том же веб-тексте (т. Е. Экземпляре JVM) этого приложения.
--whereis.jsp -
<%@ page import="java.security.*" %>
<%@ page import="java.net.URL" %>
<%
Class cls = org.joda.time.DateTimeZone.class;
ProtectionDomain pDomain = cls.getProtectionDomain();
CodeSource cSource = pDomain.getCodeSource();
URL loc = cSource.getLocation();
out.println(loc);
// it should print something like "c:/jars/MyJar.jar"
%>
Вы также можете попробовать jarscan в папке $WEBLOGIC_HOME, чтобы узнать, сможете ли вы найти jar, содержащий этот класс: https://java.net/projects/jarscan/pages/Tutorial
NoSuchMethodError
почти всегда из-за конфликтующих версий библиотеки. В этом случае я предполагаю, что в двух проектах есть несколько версий библиотек joda.
Weblogic
тянет org.joda
баночка.
Трю, добавив это в свой weblogic.xml
чтобы исключить банку, которую тянет weblogic, и вместо этого использовать вашу банку с аппликацией.
Ниже из моего приложения, вы можете посмотреть, что все мы должны удалить для нашего приложения.
<wls:container-descriptor>
<wls:prefer-application-packages>
<wls:package-name>antlr.*</wls:package-name>
<wls:package-name>org.slf4j.*</wls:package-name>
<wls:package-name>org.slf4j.helpers.*</wls:package-name>
<wls:package-name>org.slf4j.impl.*</wls:package-name>
<wls:package-name>org.slf4j.spi.*</wls:package-name>
<wls:package-name>org.hibernate.*</wls:package-name>
<wls:package-name>org.springframework.*</wls:package-name>
<wls:package-name>javax.persistence.*</wls:package-name>
<wls:package-name>org.apache.commons.*</wls:package-name>
<wls:package-name>org.apache.xmlbeans.*</wls:package-name>
<wls:package-name>javassist.*</wls:package-name>
<wls:package-name>org.joda.*</wls:package-name>
<wls:package-name>javax.xml.bind.*</wls:package-name>
<wls:package-name>com.sun.xml.bind.*</wls:package-name>
<wls:package-name>org.eclipse.persistence.*</wls:package-name>
</wls:prefer-application-packages>
<wls:show-archived-real-path-enabled>true</wls:show-archived-real-path-enabled>
</wls:container-descriptor>