2016-03-31 10 views
0

Java/JNDIでmanually follow referrals(ケースthrow)をLDAP経由でディレクトリ・サーバーから戻す方法のOracleの例を現在検討しています。問題のサンプルソースコードは、hereからダウンロードできます。問題のJNDI/LDAPを使用した古いソケット接続のリーク

コード:

// Set up environment for creating initial context 
Hashtable env = new Hashtable(11); 
env.put(Context.INITIAL_CONTEXT_FACTORY, 
    "com.sun.jndi.ldap.LdapCtxFactory"); 
env.put(Context.PROVIDER_URL, "ldap://localhost:489/o=JNDITutorial"); 

// Set referral property to throw ReferralException 
env.put(Context.REFERRAL, "throw"); 

try { 
    // Create initial context 
    DirContext ctx = new InitialDirContext(env); 

    // Set controls for performing subtree search 
    SearchControls ctls = new SearchControls(); 
    ctls.setSearchScope(SearchControls.SUBTREE_SCOPE); 

    // Do this in a loop because we don't know how 
    // many referrals there will be 
    for (boolean moreReferrals = true; moreReferrals;) { 
    try { 
     // Perform search 
     NamingEnumeration answer = ctx.search("", "(objectclass=*)", 
     ctls); 

     // Print the answer 
     while (answer.hasMore()) { 
     System.out.println(">>>" + 
      ((SearchResult)answer.next()).getName()); 
     } 

     // search completes with no more referrals 
     moreReferrals = false; 

    } catch (ReferralException e) { 

     if (! followReferral(e.getReferralInfo())) { 
     moreReferrals = e.skipReferral(); 
     } 

     // point to the new context 
     if (moreReferrals) { 
     ctx = (DirContext) e.getReferralContext(); 
     } 
    } 
    } 

    // Close the context when we're done 
    ctx.close(); 
} catch (NamingException e) { 
    e.printStackTrace(); 
} 

は、私はいくつかの方法で欠陥がこのコードを検討してください。 DirContextNamingEmuneration exibitのドキュメントclose方法はすぐにリソースを解放WICH。特に、前者はターゲットサーバへのオープンソケットを保持しています。それを閉じないと、ソケットのリークが発生します。

コードの私の理解(欠陥)がある:

  1. NamingEnumerationにanswerが閉じられることはありません。
  2. NamingExceptionの場合、最初にDirContextが閉じていないので、ブロックfinallyに移動する必要があります。
  3. e.getReferralContext()で作成されたDirContextは、ctxを上書きします。つまり、中間参照とInitialDirContextは決して閉じられずリークすることはありません。

は私の調査結果は正しいですか?

PS:followが設定されている場合のオラクルの内部実装もチェックしました。面白いのは、すべての参照コンテキストが内部で閉じられていることです。

免責事項:私はCode Reviewに最初にこのを掲載しているが、それは私のコードではありませんので、それが閉鎖されました。私はSOを試してみることを勧められました。

答えて

1

はあなたが閉鎖可能であるJNDIから取得したNamingEnumeration、そして何かを閉じる必要があります。 `NamingEnumeration`横

+0

何2.と3.についてはどうですか?だから、このコードは壊れていますよね? –

+0

はい、壊れています。閉じることができるすべてを閉じるわけではありません。 – EJP

+0

@おめでとうございます。あなたはOpenLDAPのを使用している場合のOracle .... –

関連する問題