I have an simple (webprofile) EJB 3.1 Application and try do determine the current user within an @ApplicationScoped
CDI Bean, so I use:
Principal callerPrincipal = this.sessionContext.getCallerPrincipal()
that works fine (so I can determine the name of the current user).
But after any exception in any (other) EJB this invocation does not work any more (I need to restart the Server)! Instead of returning the caller principal the method throws this exception.
Caused by: java.lang.NullPointerException
at com.sun.ejb.containers.EJBContextImpl.getCallerPrincipal(EJBContextImpl.java:421)
at de.mytest.service.CurrentUserService.getCurrentUserId(CurrentUserService.java:102)
Does anybody can give me a hint what I am doing wrong?
Implementation Details:
Server 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);
}
The EJB Facad which resist between the Faces Controller and the CDI Service
@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>
The reason it doesn't work is because your SessionContext object is declared as a global variable and since you are using @ApplicationScope, the ititialization of that resource via IoC will be done only once when the app is built.
If you want to keep the bean as @ApplicationScope, i would recommend you to try accessing the SessionContext each time you need it manually from within the method that performs the action but instead of IoC use the JNDI API manually. See the example how to see hot to perform a JNDI lookup to access a resource manually using:
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);
}
//..
}
If you are interested in knowing about more ways of accessing the SessionContext, have a look at this link where i found that code snipet:
http://javahowto.blogspot.com/2006/06/4-ways-to-get-ejbcontext-in-ejb-3.html
I hope this helps
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With