NoClassDefFoundError с использованием JAR из другого проекта

Кажется, в этой области есть ряд вопросов по SO, но я не смог найти ни одного именно с моим сценарием:

У меня есть два проекта в Eclipse: Core и Interface.

В проекте Core у меня есть 5 файлов .jar, которые содержат полезные классы и так далее. Допустим, одна из банок называется DAO.

В проекте интерфейса я перешел к пути сборки (щелкнув правой кнопкой мыши> Путь сборки> Настроить путь сборки...) и перешел в раздел «Проекты», а затем добавил основной проект.

Сначала проект Interface по-прежнему не мог видеть классы в DAO.jar, что меня смутило, но я обнаружил, что, перейдя в путь сборки основного проекта и установив флажок рядом с DAO.jar (для экспорта), компилятор остановился. жаловался, и я смог использовать классы из DAO.jar.

(Чтобы быть конкретным, я делаю веб-приложение Java с сервлетами, JSP и т. д., работающее на локальном сервере Tomcat.)

Я создаю проект, но когда я перехожу к сервлету, где метод Get использует класс из DAO.jar, я получаю NoClassDefFoundError. Вот трассировка стека:

java.lang.ClassNotFoundException: dao.DirectSqlVisitorImpl
    org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1702)
    org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1547)
    java.lang.ClassLoader.defineClass1(Native Method)
    java.lang.ClassLoader.defineClass(ClassLoader.java:792)
    java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
    org.apache.catalina.loader.WebappClassLoader.findClassInternal(WebappClassLoader.java:2928)
    org.apache.catalina.loader.WebappClassLoader.findClass(WebappClassLoader.java:1174)
    org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1669)
    org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1547)
    interface.DonationsServletController.doGet(DonationsServletController.java:79)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
    org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)

Я понял, что JRE не может найти определение класса DirectSqlVisitorImpl во время выполнения, даже несмотря на то, что проверка ошибок Eclipse позволяет ему летать теперь, когда я настроил свой путь сборки (на первый взгляд) правильным способом.

Итак, что мне нужно сделать, чтобы убедиться, что jar втягивается в проект Interface через проект Core?

В качестве примечания, я бы предпочел не делать что-то вроде добавления банок непосредственно в проект интерфейса, поскольку проект Core может использоваться другими проектами, и я хотел бы иметь модификации каскада основного проекта для всех зависимых проектов. .

Спасибо!


person Matt Mc    schedule 01.03.2014    source источник
comment
Вы пытались запустить его с отладчиком Neatbeans? Это может быть решено только clean and build   -  person    schedule 01.03.2014
comment
@Desolator Я использую Eclipse. Я несколько раз чистил сервер Tomcat и перестраивал его, но безрезультатно.   -  person Matt Mc    schedule 02.03.2014


Ответы (3)


Ваша проблема заключается в разнице между путем к классам, используемым eclipse при компиляции вашего кода, и путем к классам, используемым во время выполнения tomcat. Я имел дело с этим в настольном приложении на основе OSGi, хотя я еще не научился упаковывать приложение JavaEE в виде отдельных компонентов. Тем не менее, я могу сказать вам, что путь к ответу заключается в том, чтобы научиться создавать файлы WAR и/или EAR, чтобы библиотеки в одном экспортировались пакетом, а другой мог их импортировать.

person dsh    schedule 01.03.2014

Одним из решений может быть добавление зависимых банок в папку tomcat lib. то есть /lib.

person pundit    schedule 01.03.2014
comment
Можете ли вы объяснить, как именно это делается, как ряд шагов? Спасибо. - person Matt Mc; 02.03.2014

Хотя другие ответы здесь могут быть в некотором отношении полезны, в целом они неполны.

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

Кажется, dsh был прав в том, что моя проблема заключается в разнице между путем к классам, используемым eclipse при компиляции моего кода, и путем к классам, используемым во время выполнения tomcat. Или, точнее, файл jar DAO существует в моем проекте, но не развертывается на сервере tomcat.

Чтобы решить эту проблему, я перешел в «Свойства моего проекта»> «Сборка веб-развертывания»> «Добавить...»> «Архивы из рабочей области»> «Добавить…».

Затем я выбрал банку DAO и добавил ее. Затем проект был построен и работал нормально, без NoClassDefFoundError. Так что моя проблема была решена, по сути.

Однако я не уверен, что произойдет, если я изменю/обновлю файлы jar в проекте Core.

person Matt Mc    schedule 02.03.2014
comment
Я думал, что проблема связана с экспортом библиотек из одного WAR/EAR в другой. Основываясь на вашем решении, чтобы упростить ситуацию, просто поместите банки в каталог WEB-INF/lib/. Eclipse автоматически включит их в путь к классам во время компиляции и автоматически развернет их. Таким образом, нет необходимости добавлять их в путь сборки проекта и специально настраивать сборку развертывания. - person dsh; 03.03.2014
comment
@dsh Интересно, это имеет смысл как обычный способ сделать это. Оставлю пока как есть. Однако было бы полезно знать, как заставить их автоматически развертываться из другого проекта. - person Matt Mc; 03.03.2014