Проблема с EJB - сессионный компонент и сервлет с отслеживанием состояния

У меня есть код сервлета, который вызывает код сеансового компонента ejb с сохранением состояния следующим образом:

public class UsesBeansSF extends HttpServlet {   
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
    response.setContentType("text/html;charset=UTF-8");
    PrintWriter out = response.getWriter();
    try {
          // do something
       }

    finally {}
 } 

private SessionBeanSFRemote lookupSessionBeanSFRemote() {
    try {
        Context c = new InitialContext();
        return (SessionBeanSFRemote) c.lookup("java:global/MyEJBSF/SessionBeanSF!ejbSF.SessionBeanSFRemote");
    } catch (NamingException ne) {
        Logger.getLogger(getClass().getName()).log(Level.SEVERE, "exception caught", ne);
        throw new RuntimeException(ne);
    }
}

}

Этот код хорошо работает без линии между знаками *. Однако, когда я добавляю в эту строку SessionBeanSFRemote sessionBeanSF = lookupSessionBeanSFRemote () (означает вызов сеансового компонента с отслеживанием состояния), код выдает ошибку. Фактически, мне нужно вызвать сессионный компонент без сохранения состояния, чтобы выполнить некоторую работу. Кто-нибудь может мне помочь, почему это происходит? Заранее спасибо.

Сообщение об ошибке следующее:

Тип сообщения об исключении

descriptionThe server encountered an internal error () that prevented it from fulfilling this request.

исключение

javax.servlet.ServletException: PWC1392: Error instantiating servlet class websSF.comsSF.UsesBeansSF

основная причина

com.sun.enterprise.container.common.spi.util.InjectionException: 
         Error creating managed object for class websSF.comsSF.UsesBeansSF

основная причина

java.lang.reflect.InvocationTargetException

основная причина

java.lang.RuntimeException: javax.naming.NamingException: 
Lookup failed for 'java:global/MyEJBSF/SessionBeanSF!ejbSF.SessionBeanSFRemote' in SerialContext  
[Root exception is javax.naming.NamingException: 
ejb ref resolution error for remote business interfaceejbSF.SessionBeanSFRemote [Root exception is java.lang.NullPointerException]]

основная причина

javax.naming.NamingException: 
Lookup failed for 'java:global/MyEJBSF/SessionBeanSF!ejbSF.SessionBeanSFRemote' in SerialContext  
[Root exception is javax.naming.NamingException: 
ejb ref resolution error for remote business interfaceejbSF.SessionBeanSFRemote
[Root exception is java.lang.NullPointerException]]

основная причина

javax.naming.NamingException: ejb ref resolution error for remote business 
interfaceejbSF.SessionBeanSFRemote [Root exception is java.lang.NullPointerException]

основная причина

java.lang.NullPointerException
note The full stack traces of the exception and its root causes are available in the GlassFish Server Open Source Edition 3.0.1 logs.

Сервер: GlassFish Server Open Source Edition 3.0.1


person alessandro    schedule 01.01.2012    source источник
comment
Вы должны сообщить нам об ошибках, которые вы получаете. Мы не гадалки: P   -  person Mr.J4mes    schedule 01.01.2012
comment
Является ли bean-компонент с сохранением состояния или без состояния? Если он отслеживает состояние, вы должны искать новый экземпляр при каждом запросе, а не делиться уникальным экземпляром между всеми запросами.   -  person JB Nizet    schedule 01.01.2012
comment
@JB Nizet, bean-компонент с отслеживанием состояния. Кстати, не могли бы вы объяснить это поподробнее, это означает, что именно я должен делать.   -  person alessandro    schedule 01.01.2012
comment
Бин с отслеживанием состояния используется для поддержания разговора с 1 пользователем. Вы ищите bean-компонент с отслеживанием состояния и сохраняете его в поле сервлета. Сервлет - это синглтон: один и тот же экземпляр, если он используется одновременно всеми пользователями приложения. Вы должны объявить компонент и найти его в методе processRequest (и, возможно, сохранить его в сеансе HTTP).   -  person JB Nizet    schedule 01.01.2012
comment
Спасибо. Кстати, вы пытаетесь иметь в виду код как обновленный код моего вопроса?   -  person alessandro    schedule 01.01.2012
comment
Да, за исключением того, что следует удалить объявление поля и инициализацию (линия между *). Кстати, если вы меняете свой вопрос каждый раз, когда получаете ответ или комментарий, ответы и комментарии больше не будут иметь особого смысла.   -  person JB Nizet    schedule 01.01.2012


Ответы (1)


Я не уверен, правильно ли вы настроили свой компонент с отслеживанием состояния. Вы можете попробовать это:

@Stateful(mappedName = "ejb/myStatefulBean")
public class MyStatefulBean implements MyStatefulRemoteInterface {
   // Your implementation
}

тогда вы можете найти его с помощью:

InitialContext context = new InitialContext();
MyStatefulRemoteInterface myStatefulBean = (MyStatefulRemoteInterface) context.lookup("ejb/myStatefulBean");

Кроме того, этот bean-компонент с отслеживанием состояния должен быть сохранен в сеансе каждого клиента для повторного использования:

HttpSession clientSession = request.getSession(false);
clientSession.setAttribute("myStatefulBean", myStatefulBean);

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

person Mr.J4mes    schedule 01.01.2012
comment
Спасибо. Кстати, вы пытаетесь иметь в виду код как обновленный код моего вопроса? - person alessandro; 01.01.2012
comment
Нет, очевидно, он не это предлагает. Ваше исключение вызвано неправильным именем, переданным в lookup (). Вы вообще не меняли имя. - person JB Nizet; 01.01.2012
comment
Пульт ДУ предлагает использовать удаленный интерфейс, но шаблон использования предполагает, что используются локальные компоненты. Кроме того, вам не нужно mappedName. - person Mike Braun; 01.01.2012
comment
@MikeBraun: Мой пример - это просто пример того, как искать bean-компонент с отслеживанием состояния. Я не предлагаю ему использовать или не использовать удаленный интерфейс. Кроме того, mappedName обязательно требуется. Это параметр для метода lookup. - person Mr.J4mes; 01.01.2012
comment
@ Mr.J4mes, как вы думаете, почему требуется mappedName и почему, по вашему мнению, оно может понадобиться в методе поиска? - person Mike Braun; 01.01.2012
comment
@MikeBraun с использованием mappedName - это очень простой способ объявить EJB для поиска с помощью метода lookup. Если вы вообще ничего не делаете, скажите, пожалуйста, как можно найти боб? Как вы думаете, что нужно для поиска bean-компонента с помощью JNDI? - person Mr.J4mes; 01.01.2012
comment
@ Mr.J4mes mappedName - это пережиток прошлого. Каждому EJB назначается переносимое имя JNDI (см., Например, статью в Википедии о EJB). Просто используйте это. Использование mappedName никогда не переносимо. - person Mike Braun; 02.01.2012
comment
@MikeBraun :) У меня всегда были проблемы с глобальным именем JNDI. Не могли бы вы дать еще один ответ, объясняющий шаги за шагом, как вы можете сделать это с переносимым именем JNDI? - person Mr.J4mes; 02.01.2012