java – 此代码中的LDAP连接泄漏
发布时间:2020-12-15 08:32:15 所属栏目:Java 来源:网络整理
导读:有人可以解释一下为什么这段代码会随机“泄漏”LDAP连接吗?我可以看到已建立的TCP / IP连接数量随着时间的推移而增加,并且在某个阶段这会引发问题.我试着摆弄com.sun.jndi.ldap.connect环境属性(启用池,禁用它等)但它似乎没有帮助. 这意味着我的蹩脚代码已
有人可以解释一下为什么这段代码会随机“泄漏”LDAP连接吗?我可以看到已建立的TCP / IP连接数量随着时间的推移而增加,并且在某个阶段这会引发问题.我试着摆弄com.sun.jndi.ldap.connect环境属性(启用池,禁用它等)但它似乎没有帮助.
这意味着我的蹩脚代码已经有bug了.这应该如何做得更好,并确保我从不“泄漏”LDAP连接? import java.util.ArrayList; import java.util.List; import java.util.Properties; import javax.naming.Context; import javax.naming.InitialContext; import javax.naming.NamingEnumeration; import javax.naming.NamingException; import javax.naming.directory.Attributes; import javax.naming.directory.InitialDirContext; import javax.naming.directory.SearchControls; import javax.naming.directory.SearchResult; public class LdapUtil { private String ldap_context = "ou=myunit,dc=com"; protected static String ldap_server = "ldap://ldapserver:389/"; private String ldap_prefix = "(&(uid="; private String ldap_postfix = ")(objectclass=inetOrgPerson))"; private String[] ldap_attributes = {"uid","departmentNumber","cn","postOfficeBox","mail"}; private Properties ldap_properties; private SearchControls ldap_searchcontrols; private static String ldap_principal = "uid=bind_account,cn=users,ou=myunit,dc=com"; private static String ldap_credentials = "qwerty"; private List<String> getUserAttributes(final String userId) { List<String> UserAttributes = new ArrayList<String>(); InitialDirContext ctx = null; NamingEnumeration<SearchResult> resultsEnum = null; NamingEnumeration<String> atrEnum = null; // Connect the LDAP try { ctx = new InitialDirContext(this.ldap_properties); // Prepare the query string String query = this.ldap_prefix+ userId+ this.ldap_postfix; // Query! resultsEnum = ctx.search(this.ldap_context,query,this.ldap_searchcontrols); // Enumerate the results while (resultsEnum.hasMore()) { SearchResult sr = (SearchResult) resultsEnum.nextElement(); // Get all the attributes for a hit Attributes atr = sr.getAttributes(); // Enumerate the attributes atrEnum = atr.getIDs(); while (atrEnum.hasMore()) { String nextid = atrEnum.nextElement(); String nextattribute = atr.get(nextid).toString(); UserAttributes.add(nextattribute); } } } catch ( Exception eom ) { System.out.println("LDAP exception"); } finally { try { if (atrEnum!=null) atrEnum.close(); if (resultsEnum!=null) resultsEnum.close(); if (ctx!=null) ctx.close(); } catch (NamingException eo) { // nothing } catch (NullPointerException eo) { // Nothing } } return UserAttributes; } /* * Parses the LDAP search results and searches for selected attribute. */ private String getAttribute (final List<String> attributes,final String attribuutti) { String result = null; // Let's go through all attributes for (int i = 0; i < attributes.size(); i++) { String attribute = attributes.get(i).toString(); // Look for match if (attribute.startsWith(attribuutti)) { // Return the value after the space int k = attribute.indexOf(" "); result = attribute.substring(k+1,attribute.length()); } } return result; } public LdapUtil(String remoteuser) { // Pre-initialize LDAP connection related properties this.ldap_properties = new Properties(); this.ldap_properties.put(Context.INITIAL_CONTEXT_FACTORY,"com.sun.jndi.ldap.LdapCtxFactory"); this.ldap_properties.put(Context.PROVIDER_URL,ldap_server) ; this.ldap_properties.put(Context.REFERRAL,"follow" ); this.ldap_properties.put(Context.SECURITY_AUTHENTICATION,"simple"); this.ldap_properties.put(Context.SECURITY_PRINCIPAL,ldap_principal); this.ldap_properties.put(Context.SECURITY_CREDENTIALS,ldap_credentials); this.ldap_properties.put("com.sun.jndi.ldap.read.timeout","10000"); this.ldap_properties.put("com.sun.jndi.ldap.connect.timeout","10000"); // Tried with both pooling and without - doesn't solve problems this.ldap_properties.put("com.sun.jndi.ldap.connect.pool","false"); // Pre-initialize LDAP search controls this.ldap_searchcontrols = new SearchControls(); this.ldap_searchcontrols.setSearchScope(SearchControls.SUBTREE_SCOPE); this.ldap_searchcontrols.setReturningAttributes(this.ldap_attributes); // The List for attributes List<String> attributes = null; attributes = getUserAttributes(remoteuser); } } 解决方法
一个明显的问题是你的finally块是错误的. Ff close抛出异常,不会调用以下close方法.总是写下这样的代码:
final Res res = acquire(); try { use(res); } finally { res.release(); } 即使这意味着嵌套尝试 – 终于. (如果您使用的是旧版本的Sun JRE,则在例外情况下LDAP(和Kerberos)资源泄漏存在问题.“SunSolve” page) (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |