2012-05-14 11 views
6

Mam proste (webprofile) EJB 3.1 wniosku i spróbować ustalić, czy bieżący użytkownik w @ApplicationScoped CDI Bean, więc używam:NullPointerException w sessionContext.getCallerPrincipal()

Principal callerPrincipal = this.sessionContext.getCallerPrincipal() 

że działa dobrze (tak ja może określić nazwę bieżącego użytkownika).

Ale po jakimkolwiek wyjątku w dowolnym (innym) EJB to wywołanie już nie działa (muszę zrestartować serwer)! Zamiast zwracania nazwy użytkownika wywołującego metoda generuje ten wyjątek.

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

Czy ktoś może mi dać wskazówkę, co robię źle?


Szczegóły realizacji:

serwera 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 których oprzeć pomiędzy kontrolerem twarze i CDI Służby

@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

Dlaczego nie czyni go SessionScoped? –

+1

To wygląda jak usterka Glassfish. –

+0

Jeśli tworzysz aplikację, która po prostu robi to, co potrafisz, możesz odtworzyć to zachowanie? Jeśli tak, zachęcam do zgłoszenia błędu. – Preston

Odpowiedz

3

Powód to nie działa, ponieważ obiekt jest SessionContext jest zadeklarowana jako zmienną globalną i od używasz @ApplicationScope, Wdrożenie tego zasobu za pośrednictwem IoC nastąpi tylko raz, gdy aplikacja zostanie zbudowana.

Jeśli chcesz zachować komponent bean jako @ApplicationScope, poleciłbym spróbować uzyskać dostęp do SessionContext za każdym razem, gdy potrzebujesz go ręcznie z metody, która wykonuje akcję, ale zamiast IoC użyj ręcznie interfejsu API JNDI. Patrz przykład jak zobaczyć gorący, aby wykonać wyszukiwanie JNDI, aby uzyskać dostęp do zasobu ręcznie przy użyciu:

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); 
     } 
//.. 

} 

Jeśli jesteś zainteresowany wiedząc o więcej sposobów dostępu do SessionContext, spojrzeć na ten link gdzie znalazłem że kod snipet:

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

mam nadzieję, że to pomoże

+0

Mogę potwierdzić, że masz rację: działało idealnie po przejściu na '@ Stateless' – Ralph