There seems to be an issue in the clean-up process on Windows machines. I've been running on MacOS without any problems but the same code fails for my team members running Windows.
I've been able to reproduces this issue in a virtual machine (I used this Windows 10 VirtualBox Image) and the Corretto 8 JDK for Windows x64.
What seems to happen is that the tests run fine, but lastly the temp file clean-up is initiated here:
|
public void afterAll(final ExtensionContext context) throws Exception { |
|
final ExtensionContext.Store store = getStore(context); |
|
final Path tempNativeLibraries = store.remove(context, Path.class); |
|
if (tempNativeLibraries != null) { |
|
LOGGER.fine(() -> "Deleting all native library files at " + tempNativeLibraries); |
|
Files.walk(tempNativeLibraries) |
|
.sorted(Comparator.reverseOrder()) |
|
.peek(path -> LOGGER.fine(() ->"Deleting file/directory located at " + path)) |
|
.forEach(ThrowingConsumer.wrap(Files::delete)); |
|
} |
|
} |
First file is deleted ok: C:\Users\User\AppData\Local\Temp\native-libraries1602891640003380154\sqlite4java-win32-x86-1.0.392.dll
Second file fails: C:\Users\User\AppData\Local\Temp\native-libraries1602891640003380154\sqlite4java-win32-x64-1.0.392.dll
presumably because the DLL was loaded.
Stack trace:
java.lang.RuntimeException: Error processing consumer
at com.mkobit.junit.jupiter.aws.dynamodb.EmbeddedDynamoDBExtension$ThrowingConsumer.lambda$wrap$0(EmbeddedDynamoDBExtension.java:142)
at java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:183)
at java.util.stream.ReferencePipeline$11$1.accept(ReferencePipeline.java:440)
at java.util.ArrayList.forEach(ArrayList.java:1257)
at java.util.stream.SortedOps$RefSortingSink.end(SortedOps.java:395)
at java.util.stream.Sink$ChainedReference.end(Sink.java:258)
at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:483)
at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:472)
at java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:150)
at java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:173)
at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
at java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:485)
at com.mkobit.junit.jupiter.aws.dynamodb.EmbeddedDynamoDBExtension.afterAll(EmbeddedDynamoDBExtension.java:72)
at org.junit.jupiter.engine.descriptor.ClassTestDescriptor.lambda$invokeAfterAllCallbacks$11(ClassTestDescriptor.java:396)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:72)
at org.junit.jupiter.engine.descriptor.ClassTestDescriptor.lambda$invokeAfterAllCallbacks$12(ClassTestDescriptor.java:396)
at java.util.ArrayList.forEach(ArrayList.java:1257)
at org.junit.jupiter.engine.descriptor.ClassTestDescriptor.invokeAfterAllCallbacks(ClassTestDescriptor.java:396)
at org.junit.jupiter.engine.descriptor.ClassTestDescriptor.after(ClassTestDescriptor.java:221)
at org.junit.jupiter.engine.descriptor.ClassTestDescriptor.after(ClassTestDescriptor.java:74)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:119)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:72)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:119)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:71)
at java.util.ArrayList.forEach(ArrayList.java:1257)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:110)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:72)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:95)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:71)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:32)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:51)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:220)
at org.junit.platform.launcher.core.DefaultLauncher.lambda$execute$6(DefaultLauncher.java:188)
at org.junit.platform.launcher.core.DefaultLauncher.withInterceptedStreams(DefaultLauncher.java:202)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:181)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:128)
at com.intellij.junit5.JUnit5IdeaTestRunner.startRunnerWithArgs(JUnit5IdeaTestRunner.java:69)
at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
Caused by: java.nio.file.AccessDeniedException: C:\Users\User\AppData\Local\Temp\native-libraries1602891640003380154\sqlite4java-win32-x64-1.0.392.dll
at sun.nio.fs.WindowsException.translateToIOException(WindowsException.java:83)
at sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:97)
at sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:102)
at sun.nio.fs.WindowsFileSystemProvider.implDelete(WindowsFileSystemProvider.java:269)
at sun.nio.fs.AbstractFileSystemProvider.delete(AbstractFileSystemProvider.java:103)
at java.nio.file.Files.delete(Files.java:1126)
at com.mkobit.junit.jupiter.aws.dynamodb.EmbeddedDynamoDBExtension$ThrowingConsumer.lambda$wrap$0(EmbeddedDynamoDBExtension.java:140)
... 41 more
This seems to be caused due to the file being locked by the Java Runtime at this point. If I set a break-point before the deletion and try to delete the file manually with the Windows Explorer it says The action can't be completed because the file is open in OpenJDK Platform binary
.
I'm not familiar with Windows myself but trying to delete a DLL which is loaded by the JVM seems like a messy problem:
Since this project isn't responsible for loading the DLL itself and thus (I presume) will have a hard time trying to control the life cycle, perhaps just leaving the files could be a solution? The temp directory should be wiped eventually by the OS anyway and the files are small.