[英]Stale socket connection leak with JNDI/LDAP
I am currently reviewing Oracle's examples how to manually follow referrals (case throw
) in Java/JNDI returned from a directory server via LDAP. 我目前正在查看Oracle的示例,该示例如何手动遵循通过LDAP从目录服务器返回的Java / JNDI中的引用 (case throw
)。 The example source code in question can be downloaded here . 有问题的示例源代码可以在此处下载。
The code in question: 有问题的代码:
// 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();
}
I consider this code flawed in several ways. 我认为此代码在几种方面存在缺陷。 The documentation of DirContext
and NamingEmuneration
exibit a close
method wich immediately releases resources. DirContext
和NamingEmuneration
的文档证明使用close
方法可以立即释放资源。 Especially the former holds an open socket to the target server. 特别是前者持有目标服务器的开放套接字。 Not closing it will lead to a socket leakage. 不关闭它会导致插座泄漏。
My understanding (flaws) of the code is: 我对代码的理解(缺陷)是:
answer
is never closed. NamingEnumeration answer
永远不会关闭。 DirContext
in not closed in the case of a NamingException
, should be moved to a finally
block. 如果发生NamingException
,则第一个DirContext
未关闭,应将其移动到finally
块。 DirContext
created with e.getReferralContext()
overwrite ctx
which means that intermediate referrals as well as the InitialDirContext
are never closed and lead to leak. 使用e.getReferralContext()
创建的DirContext
覆盖ctx
,这意味着中间引用以及InitialDirContext
永远不会关闭并导致泄漏。 Are my findings correct? 我的发现正确吗?
PS: I have also checked Oracle's internal implemenation in the case that follow
is set and the funny thing is all referral contexts are closed internally. PS:我还检查Oracle内部实行在该情况下, follow
设定和有趣的是所有转诊上下文内部封闭。
Disclaimer: I have posted this initially on Code Review but it was closed because it is not my code. 免责声明:我最初将其发布在Code Review上,但由于它不是我的代码,因此已关闭。 I was advised to try on SO. 建议我尝试SO。
您需要关闭NamingEnumeration以及从JNDI获得的其他任何可关闭的东西。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.