Проблема загрузчика классов с EJB
Я работаю над проектом, который включает в себя постоянную библиотеку (JPA 1.2), EJB 3 и уровень веб-презентации (JSF). Я разрабатываю приложение, используя Eclipse, и приложение публикуется в Websphere Application Server Community Edition (Geronimo 2.1.4) через плагин eclipse (но то же самое происходит, если я публикую вручную). При публикации на сервер я получаю следующую ошибку:
java.lang.NoClassDefFoundError: Could not fully load class: manager.administration.vehicles.VehicleTypeAdminBean
due to:manager/vehicles/VehicleType
in classLoader:
org.apache.geronimo.kernel.classloader.TemporaryClassLoader@18878c7
at org.apache.xbean.finder.ClassFinder.(ClassFinder.java:177)
at org.apache.xbean.finder.ClassFinder.(ClassFinder.java:146)...
В web.xml у меня есть ссылка на EJB:
<ejb-local-ref>
<ejb-ref-name>ejb/VehicleTypeAdmin</ejb-ref-name>
<ejb-ref-type>Session</ejb-ref-type>
<local>manager.administration.vehicles.VehicleTypeAdmin</local>
<ejb-link>VehicleTypeAdminBean</ejb-link>
</ejb-local-ref>
EJB-проект имеет ссылку на постоянный проект, а веб-проект имеет ссылки на оба проекта. Я не получаю никаких ошибок компиляции, поэтому я полагаю, что классы и ссылки верны.
Я не знаю, если это проблема сервера приложений, но я ранее запускал приложение на том же сервере, используя те же параметры конфигурации.
Кто-нибудь знает, в чем может быть проблема?
2 ответа
Похоже, он не может найти класс manager.vehicles.VehicleType, когда пытается создать / загрузить класс manager.administration.vehicles.VehicleTypeAdminBean.
Я сталкивался с подобными проблемами раньше. Когда загрузчик классов пытается загрузить класс, он просматривает операторы импорта (и другие объявления об использовании классов), а затем пытается загрузить эти классы и так далее, пока он не достигнет нижней части цепочки (то есть java.lang.Object). Если он не может найти один класс по цепочке (в вашем случае он выглядит так, как будто он не может загрузить VehicleType), он сообщит, что не может загрузить класс в верхней части цепочки (в вашем случае VehicleTypeAdminBean).
Класс VehicleType находится в другой банке? Если у вас есть веб-модуль и модуль EJB, у вас есть jar, содержащий класс VehicleType, в соответствующих местах. Иногда с веб-проектами вы должны поместить файлы в папку WebContent/WEB-INF/lib, иначе они не будут найдены.
Оба эти проекта развернуты отдельно (т.е. два уха? Или одно ухо и одна война?) Или они вместе (то есть одно ухо с кувшинами и война внутри?). Я предполагаю, что второе, учитывая, что вы объявили свой EJB локальным?
Банки, от которых вы зависите, также должны быть объявлены в ваших файлах MANIFEST.MF в проектах, которые его используют.
Я работаю на догадках, так как не знаю структуру вашего проекта. Показ, который помог бы совсем немного. Но я все еще проверю, где находится VehicleType относительно вашего класса EJB. Вы можете обнаружить, что это не там, где вы думаете, что это пакет или время выполнения.
Спасибо @Chris за идею WebContent/WEB-INF/lib! это работает для меня, выполнив следующие действия:
1- Экспортируйте мои EJB-файлы в JAR (MyEJBs.jar). 2- Я создал еще один JAR-файл с помощью your_installation_path/IBM/SDP/runtimes/your_version/binCreateEJBStrub.bat через CMD.exe, выполнив следующую команду:
createEJBStubs.bat <my_path>/MyEJBs.jar -newfile –quiet
3- Новый jar будет автоматически создан в том же каталоге, что и MyEJBs.jar с именем MyEJBs_withStubs.jar
4- Поместите новую банку в WebContent/WEB-INF/lib
5- Позвоните своим EJB по:
MyEJBRemote eJBRemote;
InitialContext ic = new InitialContext();
obj = ic.lookup("your_ejb_name_jndi");
eJBRemote = (MyEJBRemote ) PortableRemoteObject.narrow(obj,
MyEJBRemote.class);
eJBRemote = (MyEJBRemote ) obj;
Теперь вы можете вызывать свои EJB из другого EAR