[英]Stale socket connection leak with JNDI/LDAP
我目前正在查看Oracle的示例,该示例如何手动遵循通过LDAP从目录服务器返回的Java / JNDI中的引用 (case throw
)。 有问题的示例源代码可以在此处下载。
有问题的代码:
// 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();
}
我认为此代码在几种方面存在缺陷。 DirContext
和NamingEmuneration
的文档证明使用close
方法可以立即释放资源。 特别是前者持有目标服务器的开放套接字。 不关闭它会导致插座泄漏。
我对代码的理解(缺陷)是:
answer
永远不会关闭。 NamingException
,则第一个DirContext
未关闭,应将其移动到finally
块。 e.getReferralContext()
创建的DirContext
覆盖ctx
,这意味着中间引用以及InitialDirContext
永远不会关闭并导致泄漏。 我的发现正确吗?
PS:我还检查Oracle内部实行在该情况下, follow
设定和有趣的是所有转诊上下文内部封闭。
免责声明:我最初将其发布在Code Review上,但由于它不是我的代码,因此已关闭。 建议我尝试SO。
您需要关闭NamingEnumeration以及从JNDI获得的其他任何可关闭的东西。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.