RLK.JNDI

RLK (リソースリーク) 指摘は、割り当てられたリソースが使用後に適切に破棄されなかった場合に報告されます。リソースが適切に破棄されないと、次のような問題につながる可能性があります。

  • 開いているファイル数が多すぎる
  • 必要なときにアプリケーションが一時ファイルにアクセスできない

警告 RLK.JNDI は、JNDI コンテキストが終了時に閉じられていないことを示します。

脆弱性とリスク

ストリーム、接続、グラフィックオブジェクトなどのリソースは、明示的に閉じられる必要があります。閉じる操作により、トランザクションをアンブロックすることや、ファイルシステム内のファイルの変更をフラッシュすることができます。リソースは、最終的にはガーベッジコレクタにより閉じられますが、ガーベッジコレクションが開始される前にリソースの枯渇が発生する可能性があります。リソースの性質によっては、別のリソース割り当ての失敗時に、さまざまな例外がスローされます。次のような例外があります:java.io.FileNotFoundException:開かれたファイルが多すぎるか、データベース接続が多すぎます。

軽減と防止

重要でないと考えられるリソースであっても、メソッドを持つリソースはすべて明示的に閉じてください。こうすることで、将来的なコード変更時にもこのようなエラーから安全が保たれます。

例 1

コピー
     public NamingEnumeration<SearchResult> search(final String providerURL,
                                                   final String name,
                                                   final String filter,
                                                   final SearchControls cons) {
         try {
             Hashtable environment = new Hashtable();
             environment.put(INITIAL_CONTEXT_FACTORY, INITIAL_CONTEXT_FACTORY);
             environment.put(Context.PROVIDER_URL, providerURL);
             environment.put(Context.SECURITY_AUTHENTICATION, SECURITY_AUTHENTICATION);
             InitialLdapContext context = new InitialLdapContext(environment, null);
 
             NamingEnumeration<SearchResult> result = context.search(name, filter, cons);  // Resource allocated
             return result;
         } catch (NamingException e) {
             System.err.println("LDAP search failed: " + e.getMessage());
         }
         return null;
     }

RLK.JNDI が 34 行目のスニペットに対して報告されています。JNDI コンテキスト 'context' が終了時に閉じられていません。

例 2

コピー
     public NamingEnumeration<SearchResult> search(final String providerURL,
                                                   final String name,
                                                   final String filter,
                                                   final SearchControls cons) {
         try {
             Hashtable environment = new Hashtable();
             environment.put(INITIAL_CONTEXT_FACTORY, INITIAL_CONTEXT_FACTORY);
             environment.put(Context.PROVIDER_URL, providerURL);
             environment.put(Context.SECURITY_AUTHENTICATION, SECURITY_AUTHENTICATION);
 
             InitialLdapContext context = new InitialLdapContext(environment, null); // Resource allocated
 
             try {
                 NamingEnumeration<SearchResult> result = context.search(name, filter, cons);
                 return result;
             } finally {
                 context.close(); // Resource released
             }
         } catch (NamingException e) {
             System.err.println("LDAP search failed: " + e.getMessage());
         }
 
         return null;
     }

例 1 のスニペットを修正しました。 フィールドは、RLK.JNDI は報告されていません。

拡張機能

このチェッカーは、Klocwork knowledge base (ナレッジベース) を利用して拡張できます。詳細については、Java 解析のチューニングを参照してください。