UF.JNDI

当尝试使用已被释放的资源时,就会报告 UF(使用已释放)问题。UF.JNDI 警告表明尝试使用已关闭的 JNDI 上下文。

示例 1

复制
     public void scan(Name name, String... filters) {
         try {
             DirContext ctx = initContext();
             try {
                 for (final String filter : filters) {
                     search(name, filter, ctx);
                 }
             } finally {
                 ctx.close();
             }
         } catch (NamingException e) {
             e.printStackTrace();
         }
     }
 
     private DirContext initContext() throws NamingException {
         Hashtable env = new Hashtable(11);
         env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
         env.put(Context.PROVIDER_URL, "ldap:///o=JndiSample,dc=example,dc=com");
 
         DirContext ctx = new InitialDirContext(env);
         return ctx;
     }
 
     private void search(Name name, String filter, DirContext ctx) throws NamingException {
         try {
             final SearchControls searchControls = new SearchControls();
             searchControls.setReturningAttributes(necessaryItemAttributes);
             searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);
             final NamingEnumeration<SearchResult> resultNamingEnumeration = ctx.search(name, filter, searchControls);
         } catch (NamingException e) {
             ctx.close();
         }
     }

针对第 30 行的代码段报告 UF.JNDI:在方法 scan 的 for 循环中访问 JNDI 上下文 ctx(请参阅第 54 行)。这将导致出现问题,因为可能在之前的某一次迭代中,由于第 56 行的方法 search 发生异常而关闭 ctx。

示例 2

复制
     public void scan(Name name, String... filters) {
         try {
             DirContext ctx = initContext();
             try {
                 for (final String filter : filters) {
                     search(name, filter, ctx);
                 }
             } finally {
                 ctx.close();
             }
         } catch (NamingException e) {
             e.printStackTrace();
         }
     }
 
     private DirContext initContext() throws NamingException {
         Hashtable env = new Hashtable(11);
         env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
         env.put(Context.PROVIDER_URL, "ldap:///o=JndiSample,dc=example,dc=com");
 
         DirContext ctx = new InitialDirContext(env);
         return ctx;
     }
 
     private void search(Name name, String filter, DirContext ctx) throws NamingException {
         final SearchControls searchControls = new SearchControls();
         searchControls.setReturningAttributes(necessaryItemAttributes);
         searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);
         final NamingEnumeration<SearchResult> resultNamingEnumeration = ctx.search(name, filter, searchControls);
     }

来自之前部分的代码段经过了修复。方法“search”不再关闭流。现在,它通过“scan”方法来关闭,即开启该流的方法。通常,通过最初用来分配资源的相同方法来释放资源是良好的编码做法。