2012-05-14 2 views
6

У меня есть простой (webprofile) EJB 3.1 приложения и попытаться сделать определение текущего пользователя в пределах @ApplicationScoped КДИ Bean, так что я использую:NullPointerException в sessionContext.getCallerPrincipal()

Principal callerPrincipal = this.sessionContext.getCallerPrincipal() 

, что работает отлично (так что я может определять имя текущего пользователя).

Но после каких-либо исключений в любом (другом) EJB этот вызов больше не работает (мне нужно перезагрузить сервер)! Вместо того, чтобы возвращать основной вызов вызывающего, метод выдает это исключение.

Caused by: java.lang.NullPointerException 
at com.sun.ejb.containers.EJBContextImpl.getCallerPrincipal(EJBContextImpl.java:421) 
at de.mytest.service.CurrentUserService.getCurrentUserId(CurrentUserService.java:102) 

ли кто-нибудь может дать мне намек, что я делаю не так?


Детали реализации:

сервера GlassFish 3.1.2

CurrentUserService:

@ApplicationScoped 
public class CurrentUserService { 

    @Resource 
    private SessionContext sessionContext; 

public long getCurrentUserId() { 

     if (this.sessionContext == null) { 
      throw new RuntimeException("initialization error, sessionContext must not be null!"); 
     } 

/*line 102 */  Principal callerPrincipal = this.sessionContext.getCallerPrincipal(); 
     if (callerPrincipal == null) { 
      throw new RuntimeException("callerPrincipal must not be null, but it is"); 
     } 

     String name = callerPrincipal.getName(); 
     if (name == null) { 
      throw new RuntimeException("could not determine the current user id, because no prinicial in session context"); 
     } 

     return this.getUserIdForLogin(name);   
    } 

EJB-Facad, которые сопротивляются между контроллером Лики и КДИ службы

@Stateless 
@RolesAllowed("myUser") 
public class TeilnehmerServiceEjb { 

    @Inject 
    private CurrentUserService currentUserService; 

    public long currentUserId() { 
     return = currentUserService.getCurrentUserId(); 
    } 
} 

web.xml

<security-constraint> 
    <web-resource-collection> 
     <web-resource-name>All Pages</web-resource-name> 
     <url-pattern>/*</url-pattern> 
    </web-resource-collection> 
    <auth-constraint> 
     <role-name>myUser</role-name> 
    </auth-constraint> 
</security-constraint> 

<login-config> 
    <auth-method>BASIC</auth-method> 
    <realm-name>mySecurityRealm</realm-name> 
</login-config> 

GlassFish-web.xml

<security-role-mapping> 
    <role-name>myUser</role-name> 
    <group-name>APP.MY.USER</group-name> 
</security-role-mapping> 
+1

Почему бы не сделать это SessionScoped? –

+1

Это похоже на дефект Glassfish. –

+0

Если вы создаете приложение, которое просто делает то, что вы описываете, вы можете воспроизвести поведение? Если это так, я бы посоветовал вам указать ошибку. – Preston

ответ

3

Причина это не работает, потому что ваш объект SessionContext объявляется как глобальная переменная, и так как вы используете @ApplicationScope, инициализация этого ресурса через IoC будет выполняться только один раз, когда приложение будет построено.

Если вы хотите сохранить bean как @ApplicationScope, я бы порекомендовал вам попробовать получить доступ к SessionContext каждый раз, когда вам это нужно вручную, из метода, который выполняет действие, но вместо IoC использует JNDI API вручную. Смотрите пример, как увидеть горячий, чтобы выполнить JNDI поиск, чтобы получить доступ к ресурсу вручную с помощью:

public long getCurrentUserId() { 
     //.. 
    try { 
      InitialContext ic = new InitialContext(); 
      SessionContext sessionContext=(SessionContext) ic.lookup("java:comp/env/sessionContext"); 

      System.out.println("look up injected sctx: " + sessionContext); 

    //Now do what you want with the Session context: 
     Principal callerPrincipal = sessionContext.getCallerPrincipal(); 
    //.. 
     } catch (NamingException ex) { 
      throw new IllegalStateException(ex); 
     } 
//.. 

} 

Если вы заинтересованы в получении информации о более способов доступа к SessionContext, посмотрите на эту ссылку, где я нашел что код snipet:

http://javahowto.blogspot.com/2006/06/4-ways-to-get-ejbcontext-in-ejb-3.html

Я надеюсь, что это помогает

+0

Я могу подтвердить, что вы правы: он отлично работал после перехода на '@ Stateless' – Ralph