元柔道整復師エンジニアBlog

- 元柔道整復師エンジニアBlog -

『 エンジニアをリングする。』

【Java】FileNotFoundExceptionによる「ファイルを開きすぎです」の表示が多数出た場合の対処方法

環境

事象

エラーログにて「ファイルを開きすぎです」というFileNotFoundExceptionが多数表示される。

Caused by: java.io.FileNotFoundException: /usr/local/apache-tomcat-8.5.23/webapps/sample/WEB-INF/lib/sample.jar (ファイルを開きすぎです)
        at java.util.zip.ZipFile.open(Native Method)
        at java.util.zip.ZipFile.<init>(ZipFile.java:225)
        at java.util.zip.ZipFile.<init>(ZipFile.java:155)
        at java.util.jar.JarFile.<init>(JarFile.java:166)
        at java.util.jar.JarFile.<init>(JarFile.java:103)
   ・
   ・
 (省略)
   ・
   ・
Caused by: java.io.FileNotFoundException: /usr/local/apache-tomcat-8.5.23/webapps/sample/WEB-INF/lib/sample.jar (ファイルを開きすぎです)
        at java.util.zip.ZipFile.open(Native Method)
        at java.util.zip.ZipFile.<init>(ZipFile.java:225)
        at java.util.zip.ZipFile.<init>(ZipFile.java:155)
        at java.util.jar.JarFile.<init>(JarFile.java:166)
        at java.util.jar.JarFile.<init>(JarFile.java:103)

原因

  • プロセスのクローズ漏れによるエラーが原因

ProcessBuilderを使用すると、バックグラウンドでInputStream・OutputStream・ErrorStreamが勝手にオープンされるため、全てのストリームをクローズしないとリソース不足に陥るかららしいです。

package sample;

import java.io.IOException;

public class ProcessExecuter {
  
    public void execute(String... command) throws IOException {
        ProcessBuilder processBuilder = new ProcessBuilder(command);
        Process process = processBuilder.start();
        process.waitFor();
        process.destroy();
    }
}

対処方法

  • Process.destroy()の前に必ずすべてのストリームをcloseする。

次のように全てのストリームに対して、しっかりとクローズ処理を追加することでエラーが解消された。

package sample;

import java.io.IOException;

public class ProcessExecuter {
  
    public void execute(String... command) throws IOException {
        ProcessBuilder processBuilder = new ProcessBuilder(command);
        Process process = processBuilder.start();
        process.waitFor();
        
        // 以降追加
        process.getInputStream().close();
        process.getOutputStream().close();
        process.getErrorStream().close();
        process.destroy();
    }
}

参考まとめ