Модераторы: LSD, AntonSaburov
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> EJB3 Wrong target class, Ошибка вызова метода бина 
V
    Опции темы
Alexis
Дата 10.2.2009, 10:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 133
Регистрация: 14.8.2006
Где: Казань

Репутация: 5
Всего: 5



Мучаю потихоньку EJB3. Чувствую, что ошибка совсем глупая, но все же разобраться самостоятельно не могу.

Если слегка упростить мое творчество, то получается, что имеется класс модели User, есть Stateless бин с методом добавления пользователя:

Код

public interface Users {    
    public void addUser(User user);
}


Код

@Stateless
public class UsersImpl implements Users {
    
    @PersistenceContext(unitName="myUnit")
    private EntityManager entityManager;

    public void addUser(User user) {
        entityManager.persist(user);
    }

}


И сервлет
Код

public class UserServlet extends HttpServlet {

    @EJB 
    private Users users;

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        PrintWriter out = resp.getWriter();
        
        User user = new User();
        // ...
        users.addUser(user);
    }

}


Собираются два JAR: ejb, модель и war-файл с сервлетом. Пакуется EAR и деплоится на JBoss 5.0 GA. При вызове сервлета выкидывается ошибка:

Код

javax.ejb.EJBException: java.lang.IllegalArgumentException: Wrong target. class com.mycompany.project.ejb.UsersImpl for public void com.mycompany.project.ejb.UsersImpl.addUser(com.mycompany.project.model.User)
    org.jboss.ejb3.tx.Ejb3TxPolicy.handleExceptionInOurTx(Ejb3TxPolicy.java:77)
    org.jboss.aspects.tx.TxPolicy.invokeInOurTx(TxPolicy.java:83)
    org.jboss.aspects.tx.TxInterceptor$Required.invoke(TxInterceptor.java:190)
    org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)
    org.jboss.aspects.tx.TxPropagationInterceptor.invoke(TxPropagationInterceptor.java:76)
    org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)
    org.jboss.ejb3.tx.NullInterceptor.invoke(NullInterceptor.java:42)
    org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)
    org.jboss.ejb3.security.Ejb3AuthenticationInterceptorv2.invoke(Ejb3AuthenticationInterceptorv2.java:159)
    org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)
    org.jboss.ejb3.ENCPropagationInterceptor.invoke(ENCPropagationInterceptor.java:41)
    org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)
    org.jboss.ejb3.asynchronous.AsynchronousInterceptor.invoke(AsynchronousInterceptor.java:106)
    org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)
    org.jboss.ejb3.BlockContainerShutdownInterceptor.invoke(BlockContainerShutdownInterceptor.java:65)
    org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)
    org.jboss.aspects.currentinvocation.CurrentInvocationInterceptor.invoke(CurrentInvocationInterceptor.java:67)
    org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:102)
    org.jboss.ejb3.session.SessionSpecContainer.invoke(SessionSpecContainer.java:219)
    org.jboss.ejb3.proxy.handler.ProxyInvocationHandlerBase.invoke(ProxyInvocationHandlerBase.java:261)
    org.jboss.ejb3.proxy.handler.session.SessionSpecProxyInvocationHandlerBase.invoke(SessionSpecProxyInvocationHandlerBase.java:101)
    $Proxy196.addUser(Unknown Source)
    com.mycompany.project.webapp.UserServlet.doGet(UserServlet.java:40)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:690)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
    org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:96)

и так далее в том же духе.

Самое интересное, что так ругается он только на мою модель. Если, к примеру, передавать String с именем пользователя, а объект создавать в бине и сохранять, то все отлично работает. Чем ему не нравятся классы моей модели, когда их передают бинам, я ума ни приложу.
PM   Вверх
powerOn
Дата 10.2.2009, 12:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


software saboteur
****


Профиль
Группа: Участник
Сообщений: 4367
Регистрация: 7.10.2005

Репутация: 28
Всего: 159



А что  если интерфейс Users пометить как @Local ?


--------------------
user posted image нет времени думать - нужно писать КОД!

PM MAIL   Вверх
Alexis
Дата 11.2.2009, 10:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 133
Регистрация: 14.8.2006
Где: Казань

Репутация: 5
Всего: 5



Цитата(powerOn @ 10.2.2009,  12:43)
А что  если интерфейс Users пометить как @Local ?

Без изменений, ошибка та же.
PM   Вверх
chand0s
Дата 11.2.2009, 10:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 55
Регистрация: 19.2.2007

Репутация: 1
Всего: 3



1) Насколько я помню EJB спеку - если пометок @Local, @Remote нет - интерфейс считается локальным. 
2) Если один интерфейс загружен двумя класслоадерами - это два разных интерфейса

По моему у вас здесь именно это и произошло - jboss грузит бин (и интерфейс Users) одним класслоадером, а tomcat - другим, поэтому у вас эти "имплементации" интерфейса несовместимы. Поковыряйтесь в доке jboss'а, поищите как можно заставить tomcat использовать класслоадер jboss-овского deployer'а
PM MAIL   Вверх
Alexis
Дата 19.2.2009, 10:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 133
Регистрация: 14.8.2006
Где: Казань

Репутация: 5
Всего: 5



Цитата(chand0s @  11.2.2009,  10:24 Найти цитируемый пост)
2) Если один интерфейс загружен двумя класслоадерами - это два разных интерфейса

Судя по всему дело не в этом. Пробовал менять загрузчик для web-приложений как описано в http://www.jboss.org/community/docs/DOC-9288 не помогло.

Как ни странно, все работает, если интерфейс пометить @Remote
PM   Вверх
chand0s
Дата 19.2.2009, 15:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 55
Регистрация: 19.2.2007

Репутация: 1
Всего: 3



Цитата(Alexis @ 19.2.2009,  08:41)
Цитата(chand0s @  11.2.2009,  10:24 Найти цитируемый пост)
2) Если один интерфейс загружен двумя класслоадерами - это два разных интерфейса

Как ни странно, все работает, если интерфейс пометить @Remote

Вообще это не странно.
Подумайте сами, что происходит внутри сервера:
1) Интерфейс локальный. JBoss делает так:
  • создает экземпляр UsersImpl
  • пытается присвоить ссылку на этот экземпляр переменной Users (которая в сервлете), т.к. интерфейс локальный.
  • экземпляр UsersImpl реализует интерфейс Users, который загружен класслоадером JBoss'а, а присваивается этот экземпляр переменной, чей интерфейс Users загружен tomcat'ом. Эти интерфейсы несовместимы, присваивание невозможно, всё падает.

2) Интерфейс удаленный. Происходит примерно вот что:
  • JBoss создает экземпляр UsersImpl (на самом деле там пул Stateless-бинов, но это неважно)
  • Для переменной Users создается прокси, который знает куда и как отправлять вызовы методов (пусть даже в пределах одной JVM, но прокси все равно создается)
  • При вызове какого-нибудь метода этой переменной в сервлете, прокси сериализует параметры метода и пуляет это все туда, где это ждет JBoss. Метод выполняется, возвращает значение, это значение сериализуется и отправляется обратно.


PM MAIL   Вверх
ivg
Дата 19.2.2009, 17:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Autonomous R&D
**


Профиль
Группа: Участник
Сообщений: 686
Регистрация: 8.2.2006
Где: Екатеринбург

Репутация: 32
Всего: 81



Alexis, у вас классы модели находятся только в отдельном jar'е? В war'е их нету?
Обычно и классы модели и Enterprise бины упаковываются в один jar. В манифесте war'а (/META-INF/MANIFEST.MF) прописывается ссылка на <ejb>.jar (строка Class-Path: <ejb>.jar)
Ну и в application.xml ear'а должны быть определены оба модуля.
<ejb>.jar - имя jar файла с классами модели и Enterprise бинами.
Современные IDE делают это автоматом, либо при сборке проекта, либо при создании(настройке) проектов.
Если вы выносите классы модели в отдельный jar, то соответствующие ссылки должны быть прописаны в манифестах и <ejb>.jar и war файлов.
PM MAIL   Вверх
Alexis
Дата 19.2.2009, 18:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 133
Регистрация: 14.8.2006
Где: Казань

Репутация: 5
Всего: 5



Действительно, установил в pom.xml зависимостям ejb и модели scope равным provided. Как результат, JAR файлы не копируются в создаваемый WAR-архив. Т. е. фактически получается следующая структура:

Код

- myproject.ear
   - META-INF
      application.xml  # прописаны WEB и EJB модули
      jbos-app.xml     # прописан loader-repository
      manifest.mf      # в classpath model.jar и ejb.jar
   - ejb.jar
      manifest.mf      # в classpath model.jar
      persistence.xml
      + com.company.myproject
   + model.jar
   - webapp.war
      - META-INF
          manifest.mf      # в classpath пусто
      - WEB-INF
         + lib             # никаких ejb.jar, да и model.jar ни к чему :)


До этого EJB лежали в WAR-файле, что и вызавало проблему, которую подробно описал chand0s.

chand0s, спасибо за терпение и подробное объяснение!
ivg, спасибо за наводку на простой путь решения!
Поставил плюсы.

Это сообщение отредактировал(а) Alexis - 19.2.2009, 18:49
PM   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Java"
LSD   AntonSaburov
powerOn   tux
  • Прежде, чем задать вопрос, прочтите это!
  • Книги по Java собираются здесь.
  • Документация и ресурсы по Java находятся здесь.
  • Используйте теги [code=java][/code] для подсветки кода. Используйтe чекбокс "транслит", если у Вас нет русских шрифтов.
  • Помечайте свой вопрос как решённый, если на него получен ответ. Ссылка "Пометить как решённый" находится над первым постом.
  • Действия модераторов можно обсудить здесь.
  • FAQ раздела лежит здесь.

Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, tux.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Java EE (J2EE) и Spring | Следующая тема »


 




[ Время генерации скрипта: 0.0484 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.