2012-05-14 19 views
6

私は、単純な(webprofile)EJB 3.1アプリケーションを持っていると@ApplicationScoped CDIビーン内の現在のユーザーを決定しようとしませんので、私が使用して現在のユーザーの名前を判別できます)。のNullPointerException()

しかし、任意の(他の)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顔コントローラとCDIサービス

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

    @Inject 
    private CurrentUserService currentUserService; 

    public long currentUserId() { 
     return = currentUserService.getCurrentUserId(); 
    } 
} 
の間にレジスト あなたのSessionContextオブジェクトはグローバル変数として宣言されているため、あなたが@ApplicationScopeを使用しているので、それは動作しません

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

理由は、あります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