Closed borkdude closed 7 months ago
Maybe related: https://github.com/oracle/graal/issues/1581
Closing this issue as it has been fixed in past releases. If you can see that the problem persists in the latest snapshot, please feel free to reopen this ticket.
Updated issue using pure Java (after discovering the root cause)
When opening a lot of JarFiles without closing them, a seemingly unrelated exception is thrown in a native binary on macOS.
Repro using pure Java. This will open every jar file present in your ~/.m2 folder.
LockRepro.java:
Compile with
javac LockRepro.java
followed bynative-image LockRepro
. Then run with./lockrepro
. What I'm seeing on my Mac after printing some 253 jar file names:Note that
java LockRepro
still works and doesn't throw this exception. It printsAmount of jarFiles created: 1661
at the end on my machine.I would have expected the message in the exception using the native to be something like 'too many files open'.
Original issue using Clojure
Clj-kondo, a linter for Clojure, is built as a native binary using GraalVM.
The binary shows a problem with
RandomAccessFile
when it lints a lot of sources, while the Java version doesn't have this problem. Problem is reproducible using GraalVM 19.2.1 on macOS 10.14.6 / macOS 10.15 (19A602) / 10.15.1 (19B88). Linux users do not seem to be able to reproduce it.The problem is that
java.io.FileNotFoundException
is thrown for no apparent reason.UPDATE: meanwhile I've been able to find the cause for this problem. It happens when you have many
JarFile
objects open at a single time and you don't close them.Instructions to trigger the problem:
Build the following .jar file to a native (unzip first):
clj-kondo-2019.10.26-standalone.jar.zip
I do this using the following
reflection.json
file contains this:and compile with:
(A complete overview of how the uberjar is built and from that, the native image, can be viewed here: https://github.com/borkdude/clj-kondo/blob/9de6b455a8ccd6df7923cb480b621c42572908a1/script/compile#L1)
Before we execute clj-kondo we will populate our local maven repo with a bunch of Clojure libraries that we will lint. We need leiningen to do this and we will use this project.clj file (unzip first):
project.clj.zip
Now execute the binary
clj-kondo
as follows:The output of clj-kondo is not important so we write it to /dev/null. The exit code can be ignored as well. The most important is that it will throw an exception that we do not see in the JVM version:
Compare this to linting with the standalone jar (clj-kondo-2019.10.26-standalone.jar.zip):
That works without an exception.
Note that the error in the native only exhibits when the linted classpath is very large, not with a smaller classpath.
The error was reported in this issue in the clj-kondo repo.