2012-05-14 32 views
6

Tôi có một đơn giản (webprofile) EJB 3.1 Ứng dụng và cố gắng làm xác định người dùng hiện trong một @ApplicationScoped CDI Bean, vì vậy tôi sử dụng:NullPointerException trong sessionContext.getCallerPrincipal()

Principal callerPrincipal = this.sessionContext.getCallerPrincipal() 

rằng hoạt động tốt (vì vậy tôi có thể xác định tên của người dùng hiện tại).

Nhưng sau bất kỳ ngoại lệ nào trong bất kỳ (khác) EJB, lệnh gọi này không hoạt động nữa (tôi cần phải khởi động lại Máy chủ)! Thay vì trả lại người gọi chính, phương thức này ném ra ngoại lệ này.

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

Có ai có thể cho tôi gợi ý những gì tôi đang làm sai không?


chi tiết thực hiện:

máy chủ 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 mà cưỡng lại giữa Controller Faces và Dịch vụ

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

    @Inject 
    private CurrentUserService currentUserService; 

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

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

Tại sao không làm cho nó SessionScoped? –

+1

Điều này trông giống như một lỗi Glassfish. –

+0

Nếu bạn tạo một ứng dụng chỉ làm những gì mô tả của bạn, bạn có thể sao chép hành vi? Nếu vậy, tôi sẽ khuyến khích bạn gửi một lỗi. – Preston

Trả lời

3

Lý do nó không hoạt động là bởi vì đối tượng SessionContext của bạn được khai báo là một biến toàn cầu và kể từ khi bạn đang sử dụng @ApplicationScope, việc ititialization của tài nguyên đó thông qua IoC sẽ chỉ được thực hiện một lần khi ứng dụng được xây dựng.

Nếu bạn muốn giữ bean là @ApplicationScope, tôi khuyên bạn nên thử truy cập SessionContext mỗi lần bạn cần thủ công từ bên trong phương thức thực hiện hành động nhưng thay vì IoC sử dụng API JNDI theo cách thủ công. Xem ví dụ làm thế nào để thấy nóng để thực hiện một tra cứu JNDI để truy cập vào một tài nguyên bằng tay sử dụng:

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

} 

Nếu bạn muốn biết về cách hơn truy cập vào SessionContext, có một cái nhìn tại liên kết này nơi mà tôi tìm thấy rằng mã snipet:

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

tôi hy vọng điều này sẽ giúp

+0

Tôi có thể xác nhận rằng bạn nói đúng: Nó hoạt động hoàn hảo sau khi chuyển sang '@ Stateless' – Ralph

Các vấn đề liên quan