我目前正在审查Oracle的示例,如何在通过LDAP从目录服务器返回的Java / JNDI中manually follow referrals(大小写为throw)。有问题的示例源代码可以下载here

有问题的代码:

// 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的文档排除了一个close方法,该方法立即释放资源。特别是前者持有目标服务器的开放套接字。不关闭它会导致插座泄漏。

我对代码的理解(缺陷)是:


NamingEnumeration answer永远不会关闭。
DirContext情况下未关闭的第一个NamingException应该移至finally块。
DirContext创建的e.getReferralContext()覆盖ctx,这意味着中间引用以及InitialDirContext永远不会关闭并导致泄漏。


我的发现正确吗?

PS:在设置了follow的情况下,我还检查了Oracle的内部实现,有趣的是,所有引用上下文都在内部关闭。

免责声明:我最初在Code Review上发布了此内容,但由于它不是我的代码,因此已关闭。建议我试一下。

最佳答案

您需要关闭NamingEnumeration以及从JNDI获得的其他可关闭内容。

09-13 14:11