Description
Overview
There are various circumstances that can cause the cleanup of a temporary directory to fail. Some of these errors may indicate open or leaking file handles, issues in the implementation being tested, or problems in the test itself. Others may occur only occasionally on slow filesystems, race-conditions in asynchronous process and so on.
Currently, a test encountering such a problem will fail with something like:
org.junit.platform.commons.JUnitException: Failed to close extension context
org.junit.platform.commons.JUnitException: Failed to close extension context
at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
Caused by: java.io.IOException: Failed to delete temp directory C:\Windows\TEMP\junit-6301891027881835454. The following paths could not be deleted (see suppressed exceptions for details): <root>, ws
at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:183)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
at java.base/java.util.stream.SortedOps$RefSortingSink.end(SortedOps.java:395)
at java.base/java.util.stream.Sink$ChainedReference.end(Sink.java:258)
at java.base/java.util.stream.Sink$ChainedReference.end(Sink.java:258)
at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:510)
at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)
at java.base/java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:150)
at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:173)
at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
at java.base/java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:596)
... 2 more
Suppressed: java.nio.file.DirectoryNotEmptyException: C:\Windows\TEMP\junit-6301891027881835454
at java.base/sun.nio.fs.WindowsFileSystemProvider.implDelete(WindowsFileSystemProvider.java:272)
at java.base/sun.nio.fs.AbstractFileSystemProvider.delete(AbstractFileSystemProvider.java:105)
at java.base/java.nio.file.Files.delete(Files.java:1152)
at java.base/java.nio.file.Files.walkFileTree(Files.java:2828)
at java.base/java.nio.file.Files.walkFileTree(Files.java:2882)
... 13 more
Suppressed: java.nio.file.DirectoryNotEmptyException: C:\Windows\TEMP\junit-6301891027881835454\ws
at java.base/sun.nio.fs.WindowsFileSystemProvider.implDelete(WindowsFileSystemProvider.java:272)
at java.base/sun.nio.fs.AbstractFileSystemProvider.delete(AbstractFileSystemProvider.java:105)
at java.base/java.nio.file.Files.delete(Files.java:1152)
at java.base/java.nio.file.Files.walkFileTree(Files.java:2828)
at java.base/java.nio.file.Files.walkFileTree(Files.java:2882)
... 13 more
In my opinion, this is unfortunate and could also be considered a regression compared to JUnit 4. In JUnit 4, it was possible to work around these kinds of issues using TemporaryFolder#assureDeletion
, which allowed ignoring failed deletion of the temporary directory.
As of now, there is no way to bypass these issues in JUnit 5 unless you define @TempDir(cleanup = CleanupMode.NEVER)
or avoid using @TempDir
altogether - both of which seem undesirable.
See #4549 for a working proposal.