Finalizers Run On Exit
ID |
kotlin.no_finalizers_on_exit |
Severity |
high |
Remediation Complexity |
trivial |
Remediation Risk |
low |
Remediation Effort |
low |
Resource |
Reliability |
Language |
Kotlin |
Tags |
reliability |
Description
Reports a call to System.runFinalizersOnExit or Runtime.runFinalizersOnExit, in either the
static or the Runtime.getRuntime() instance form.
Rationale
Both methods ask the JVM to run every object’s finalizer on shutdown — including the finalizers of objects that are still reachable and still in use by other threads. A finalizer written on the assumption that its object is unreachable then runs concurrently with live code: it closes a handle another thread is writing to, frees native memory that is still mapped, and corrupts the very state the shutdown was supposed to flush.
fun configureShutdown() {
System.runFinalizersOnExit(true) // finalizers race live application threads
}
The methods have been deprecated for this reason since Java 1.2, throw
UnsupportedOperationException from Java 11 onwards, and were removed from the platform
afterwards. So the call is dead weight on an older JVM and an outright failure on a current one.
Remediation
Register a shutdown hook for the cleanup that genuinely has to happen at exit, and release
resources deterministically everywhere else — use { } for anything Closeable:
fun configureShutdown() {
Runtime.getRuntime().addShutdownHook(Thread { flushAndClose() })
}
fun read(path: Path): String {
return Files.newBufferedReader(path).use { it.readText() }
}