2012-05-14 20 views
6

tengo una sencilla (webprofile) EJB 3.1 Aplicación y tratar de no determinar que el usuario actual dentro de una @ApplicationScoped CDI Bean, así que utilizo:NullPointerException en sessionContext.getCallerPrincipal()

Principal callerPrincipal = this.sessionContext.getCallerPrincipal() 

que funciona bien (por lo que puede determinar el nombre del usuario actual).

Pero después de cualquier excepción en cualquier (otro) EJB, esta invocación ya no funciona (¡tengo que reiniciar el servidor)! En lugar de devolver el principal llamante, el método arroja esta excepción.

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

¿Alguien me puede dar una pista de lo que estoy haciendo mal?


Detalles de la implementación:

servidor 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);   
    } 

El EJB Facad que resisten entre el controlador caras y el Servicio de CDI

@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

¿Por qué no hacer que SessionScoped? –

+1

Esto se parece a un defecto de Glassfish. –

+0

Si creas una aplicación que solo hace lo que describes, ¿puedes reproducir el comportamiento? Si es así, te animo a que presentes un error. – Preston

Respuesta

3

La razón por la que no funciona es porque su objeto SessionContext se declara como una variable global y dado que está utilizando @ApplicationScope, la ititialización de ese recurso a través de IoC se hará solo una vez cuando se construya la aplicación.

Si desea mantener el bean como @ApplicationScope, le recomendaría que intente acceder al SessionContext cada vez que lo necesite manualmente desde el método que realiza la acción, pero en lugar de IoC use la API JNDI manualmente. Véase el ejemplo de la forma de ver caliente para realizar una búsqueda JNDI para acceder a un recurso manualmente usando:

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

} 

Si está interesado en conocer más formas de acceder al SessionContext, echar un vistazo a este enlace donde encontré ese código snipet:

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

espero que esto ayuda a

+0

Puedo confirmar que tiene razón: Funcionó perfecto después de cambiar a '@ Stateless' – Ralph

Cuestiones relacionadas