Clean fails in Windows Docker environment with 3.4.1+
Affected version
3.4.1+
Bug description
After updating from 3.4.0 to 3.5.0, our .NET builds invoking Maven and Maven Clean plugin have started failing. The issue appears to be in JDK itself where it does not cope with the reparse points and/or symlinks that Windows Docker environment uses to map volumes into the Windows Docker containers.
The tail end of the call stack with 3.5.0 looks likes this:
Caused by: java.nio.file.NoSuchFileException: d:\j\workspace\464c76a43d7e02073ee9722b0781b2c5\PROJECT\target
at sun.nio.fs.WindowsException.translateToIOException (WindowsException.java:79)
at sun.nio.fs.WindowsException.rethrowAsIOException (WindowsException.java:97)
at sun.nio.fs.WindowsException.rethrowAsIOException (WindowsException.java:102)
at sun.nio.fs.WindowsLinkSupport.getFinalPath (WindowsLinkSupport.java:82)
at sun.nio.fs.WindowsLinkSupport.getRealPath (WindowsLinkSupport.java:242)
at sun.nio.fs.WindowsPath.toRealPath (WindowsPath.java:836)
at sun.nio.fs.WindowsPath.toRealPath (WindowsPath.java:44)
at org.apache.maven.plugins.clean.Cleaner.delete (Cleaner.java:135)
at org.apache.maven.plugins.clean.CleanMojo.execute (CleanMojo.java:265)
at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo (DefaultBuildPluginManager.java:126)
at org.apache.maven.lifecycle.internal.MojoExecutor.doExecute2 (MojoExecutor.java:328)
at org.apache.maven.lifecycle.internal.MojoExecutor.doExecute (MojoExecutor.java:316)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:212)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:174)
at org.apache.maven.lifecycle.internal.MojoExecutor.access$000 (MojoExecutor.java:75)
at org.apache.maven.lifecycle.internal.MojoExecutor$1.run (MojoExecutor.java:162)
at org.apache.maven.plugin.DefaultMojosExecutionStrategy.execute (DefaultMojosExecutionStrategy.java:39)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:159)
at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:105)
at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:73)
at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build (SingleThreadedBuilder.java:53)
at org.apache.maven.lifecycle.internal.LifecycleStarter.execute (LifecycleStarter.java:118)
at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:261)
at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:173)
at org.apache.maven.DefaultMaven.execute (DefaultMaven.java:101)
at org.apache.maven.cli.MavenCli.execute (MavenCli.java:906)
at org.apache.maven.cli.MavenCli.doMain (MavenCli.java:283)
at org.apache.maven.cli.MavenCli.main (MavenCli.java:206)
at sun.reflect.NativeMethodAccessorImpl.invoke0 (Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke (Method.java:498)
at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced (Launcher.java:283)
at org.codehaus.plexus.classworlds.launcher.Launcher.launch (Launcher.java:226)
at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode (Launcher.java:407)
at org.codehaus.plexus.classworlds.launcher.Launcher.main (Launcher.java:348)
This appears to be a know JDK issue JDK-8172711. I do not expect the Maven project to fix this. I am just filling the defect so that the next guy to hit this can find this here.
The Moby project has encountered it, too: https://github.com/moby/moby/issues/27537
After comparing Maven Clean Plugin versions 3.4.0 and 3.4.1, it is clear that the root cause of the reported issue is a major internal refactoring introduced in 3.4.1. In this release, the plugin migrated from using the legacy java.io.File API to the modern java.nio.file.Path and Files APIs for file and directory operations.
This migration brought changes such as:
- Replacing most usages of File with Path.
- Using Path.toRealPath() and other Files methods for directory and symlink handling.
- Changing the logic for directory traversal and deletion, now relying on DirectoryStream and Path-based operations. As a result, the plugin now triggers code paths in the JDK (notably Path.toRealPath()) that are known to have issues with Windows reparse points and symlinks, especially in Docker environments where volume mounts are implemented as reparse points. This can lead to NoSuchFileException errors, as described in JDK bug JDK-8172711.