Add way to delete read-only files
New feature, improvement proposal
Some plugins can create read only files which deletion throws java.nio.file.AccessDeniedException in maven-clean-plugin, it would be useful to provide a way to change file attributes before delete to fix such exception
We have the same problem, updating to 3.4.1 from 3.4.0 and clean plugin is failing to delete files and throw AccessDeniedException.
This should be a bug and not an enhancement @raydac
Caused by: java.nio.file.AccessDeniedException: C:\_Work_\git\test\main\domain\target\generated-sources\xjc\com\test\TestEnum.java
at sun.nio.fs.WindowsException.translateToIOException (WindowsException.java:89)
at sun.nio.fs.WindowsException.rethrowAsIOException (WindowsException.java:103)
at sun.nio.fs.WindowsException.rethrowAsIOException (WindowsException.java:108)
at sun.nio.fs.WindowsFileSystemProvider.implDelete (WindowsFileSystemProvider.java:275)
at sun.nio.fs.AbstractFileSystemProvider.delete (AbstractFileSystemProvider.java:105)
at java.nio.file.Files.delete (Files.java:1152)
at org.apache.maven.plugins.clean.Cleaner.delete (Cleaner.java:316)
at org.apache.maven.plugins.clean.Cleaner.delete (Cleaner.java:276)
at org.apache.maven.plugins.clean.Cleaner.delete (Cleaner.java:250)
at org.apache.maven.plugins.clean.Cleaner.delete (Cleaner.java:222)
at org.apache.maven.plugins.clean.Cleaner.delete (Cleaner.java:222)
at org.apache.maven.plugins.clean.Cleaner.delete (Cleaner.java:222)
at org.apache.maven.plugins.clean.Cleaner.delete (Cleaner.java:222)
at org.apache.maven.plugins.clean.Cleaner.delete (Cleaner.java:222)
at org.apache.maven.plugins.clean.Cleaner.delete (Cleaner.java:222)
at org.apache.maven.plugins.clean.Cleaner.delete (Cleaner.java:222)
at org.apache.maven.plugins.clean.Cleaner.delete (Cleaner.java:222)
at org.apache.maven.plugins.clean.Cleaner.delete (Cleaner.java:222)
at org.apache.maven.plugins.clean.Cleaner.delete (Cleaner.java:128)
at org.apache.maven.plugins.clean.CleanMojo.execute (CleanMojo.java:257)
PR are welcome ....
We also should to think:
- should this be the default option?
- what with errors during attribute changing
As mentioned above, this is a regression from 3.4.0, not an enhancement.
The root cause is that, at least on Windows, File::delete deletes read-only files successfully, whereas Files::delete does not.
The regression was introduced by the work on migrating to java.nio.file APIs:
- e8fea70fbb0f1dc1dbc3db4c7dd6ae8fe55d6ce4
- 091570bba9ce6a20d6ba364f22e47909fc0342e2
- cb2127f8ddb531edb67de4d9ec99555470b39e81
- bf21c555349dab05837d131fdf2ca60c9bd06d41
@slawekjaranowski I'd argue that the burden should not be on the "victims" to provide a PR. Instead, I propose to revert the problematic commits and release version 3.4.2
I think that we need to keep the migration to Path. Other work such as #243 are built on top of those commits. This work replaces Plexus by java.nio.file.PathMatcher and java.nio.file.FileVisitor, which allows for example to delegate the handling of symbolic links to Java. It is also part of a larger effort to reduce inconsistent duplications among Maven plugins (e.g., maven-clean-plugin and maven-compiler-plugin duplicate codes for iterating over files, but with slight behavioural differences that are probably unintentional).
Instead, I propose to add a force configuration option similar to rm -f in Unix. I suggest that the default value should be false for safety and for consistency with the standard usage in Unix commands. If agreed, I can volunteer for adding this option on top of #243.
Just to be clear: I'm all in favor of migrating to Path. I'm just arguing that this issue is a severe regression and that we should revert the problematic commits and release version 3.4.2 ASAP. Parallel to that, a new PR can be created (for which you can just revert the reverted commits again and add tests to it to prevent any regressions like this one). #243 is not merged yet, so it could just be rebased on the new PR.
Instead, I propose to add a
forceconfiguration option similar torm -fin Unix. I suggest that the default value should befalsefor safety and for consistency with the standard usage in Unix commands. If agreed, I can volunteer for adding this option on top of #243.
The new behavior is a regression that breaks long-standing behavior. So I believe the priority should be on fixing the regression.
Besides that, I fail to see why anyone would want to use such a configuration option with the value false?
Anyway, if such an option were to be introduced, its default value should match the way it has always behaved, so true.
We can see the 3.4.1 behaviour as a regression, or the 3.4.0 behaviour as a bug. Both views are defensible. A compromise could be to default to true for now with a warning saying that the default would change to false in a future version (that warning would not be emitted if the user explicitly set that option).
A reason for safety is that there is always a risk that the directory to delete is accidentally set to the wrong directory. Or maybe there is a symbolic link pointing outside the target directory (e.g. users created it temporarily for a test, then forgot about it) and the plugin is following symbolic links. If a file is marked as read-only, it is probably of particular importance for the user, so being conservative is a common choice.
This issue was filed just 10 days after the release of 3.4.1, while I doubt there have ever been complaints about the deletion of read-only files in the decades before 3.4.1
Anyway, to each their own. I'll just revert to 3.4.0 and leave this discussion to the powers that be.
Started a branch for the addition of a force configuration parameter. Still work in progress at the time of writing this comment.
Completed a first attempt. If any volunteer would like to build the branch locally and test, feedbacks would be welcome as there is potential for corner cases not correctly handled.
@desruisseaux I will try port a force option to 3.x branch
@anthonyvdotbe : apparently, reverting the commits may not work anyway. Oracle seems to also consider that File.delete deleting read-only files is a bug. See https://bugs.openjdk.org/browse/JDK-8355954
Context is everything. Oracle's assessment of the situation and their chosen path forward makes perfect sense to me. At the same time, introducing a force parameter with a default value of false to deal with this regression makes no sense to me.
The default should have been 'true'. Thanks for all the extra work fixing this causes to the community, disappointed. π For semver users (I know maven states they don't do semver), there should have been the original plan of 3.4.2.
This issue should be closed as fixed against version 3.5.0
Fixed on Maven 3.x by #252 and on Maven 4.x by #250.
@desruisseaux and @slawekjaranowski: Has there been any reason why you didn't make the default value true at least for the 3.x version. I also consider this a regression which should be fixed without forcing consumers to use additional flags.
@kwin : even if we didn't changed anything, the deletion of read-only files would have stopped to work in Java 25. Even with the old Maven Clean Plugin, peoples who want the old behaviour with Java 25 will need to specify a flag (a Java property) anyway.
Not deleting read-only files by default is the standard behaviour of Unix tools and of Java 25. If the value was true by default, almost nobody would bother setting the value to false. Peoples would do their everyday work with more privilege than necessary, a little bit like being administrator on a machine when not necessary. This is a small convenience compared to the damage of unintended data destruction.
Another reason is to avoid to surprise users who were not aware of that Maven particularity, and who may have expected a behaviour more consistent with the standard practice of Unix tools.
This was a surprise, I don't have a single setup not set to force now. Most are not going to be java 25 for some time. I find it a regression as well. Especially due to extra cloning maven does with releasing to the target folder that gets stuck and throws new errors. It was especially painful with spotbugs maven plugin as it clones spotbugs to target for integration tests. Forcing java 25 style when not GA seems premature when it has such a negative impact to current usage. At very least target is and has been temp space so it really should have remained as such regardless of content.
Sent from my Verizon, Samsung Galaxy smartphone Get Outlook for Androidhttps://aka.ms/AAb9ysg
From: Martin Desruisseaux @.> Sent: Wednesday, August 6, 2025 8:46:07 AM To: apache/maven-clean-plugin @.> Cc: Jeremy Landis @.>; Comment @.> Subject: Re: [apache/maven-clean-plugin] Add way to delete read-only files (Issue #109)
[https://avatars.githubusercontent.com/u/1324414?s=20&v=4]desruisseaux left a comment (apache/maven-clean-plugin#109)https://github.com/apache/maven-clean-plugin/issues/109#issuecomment-3160021277
@kwinhttps://github.com/kwin : even if we didn't changed anything, the deletion of read-only files would have stopped to work in Java 25https://bugs.openjdk.org/browse/JDK-8356195. Even with the old Maven Clean Plugin, peoples who want the old behaviour with Java 25 will need to specify a flag (a Java property) anyway.
Not deleting read-only files by default is the standard behaviour of Unix tools and of Java 25. If the value was true by default, almost nobody would bother setting the value to false. Peoples would do their everyday work with more privilege than necessary, a little bit like being administrator on a machine when not necessary. This is a small convenience compared to the damage of unintended data destruction.
Another reason is to avoid to surprise users who were not aware of that Maven particularity, and who may have expected a behaviour more consistent with the standard practice of Unix tools.
β Reply to this email directly, view it on GitHubhttps://github.com/apache/maven-clean-plugin/issues/109#issuecomment-3160021277, or unsubscribehttps://github.com/notifications/unsubscribe-auth/AAHODIZ5MF4L3XRNRHINEM33MH2I7AVCNFSM6AAAAABYBW2C76VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZTCNRQGAZDCMRXG4. You are receiving this because you commented.Message ID: @.***>
This is all good reasons however they donβt outweigh in my view breaking changes in a minor version which are for good reason perceived as regressions.
I can see both points of view.
That said, would you be okay with the new default (not deleting read-only files) alongside a helpful error message that hints what options needs to be enabled? Something along the lines of "Failed to delete X because it is read-only. Set force=true to delete read-only files."
So, the problem happens in the following circumstances, is that right?
- A plugin executed a
git clonein thetarget/directory. - The operating system (OS) is Windows.
If I understood correctly, the problem is specific to Windows because on that OS we cannot delete a read-only file. This problem does not occur on Unix because on that OS, whether we can delete the file depends on the read-only status of the directory that contains the file, not the file itself, and I verified in my local projects that git keeps the directories writeable. It only blocks the modifications of the files contained in these directories.
A possible compromise could be to add a third value to the<force> option, in addition of true and false: default (better names are welcome if there is any idea). That mode would be equivalent to true only under the following conditions:
- Only for files below a
.gitdirectory. - Only on Windows.
The default would stay an unconditional false on Unix. Would it be acceptable?
I like that idea.
Sent from my Verizon, Samsung Galaxy smartphone Get Outlook for Androidhttps://aka.ms/AAb9ysg
From: Martin Desruisseaux @.> Sent: Thursday, August 7, 2025 4:51:57 AM To: apache/maven-clean-plugin @.> Cc: Jeremy Landis @.>; Comment @.> Subject: Re: [apache/maven-clean-plugin] Add way to delete read-only files (Issue #109)
[https://avatars.githubusercontent.com/u/1324414?s=20&v=4]desruisseaux left a comment (apache/maven-clean-plugin#109)https://github.com/apache/maven-clean-plugin/issues/109#issuecomment-3163162794
So, the problem happens in the following circumstances, is that right?
- A plugin executed a git clone in the target/ directory.
- The operating system (OS) is Windows.
If I understood correctly, the problem is specific to Windows because on that OS we cannot delete a read-only file. This problem does not occur on Unix because on that OS, whether we can delete the file depends on the read-only status of the directory that contains the file, not the file itself, and I verified in my local projects that git keeps the directories writeable. It only blocks the modifications of the files contained in these directories.
A possible compromise could be to add a third value to the
- Only for files below a .git directory.
- Only on Windows.
The default would stay an unconditional false on Unix. Would it be acceptable?
β Reply to this email directly, view it on GitHubhttps://github.com/apache/maven-clean-plugin/issues/109#issuecomment-3163162794, or unsubscribehttps://github.com/notifications/unsubscribe-auth/AAHODI2AIIWV4KQ5JTAKXTD3MMHS3AVCNFSM6AAAAABYBW2C76VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZTCNRTGE3DENZZGQ. You are receiving this because you commented.Message ID: @.***>
I can confirm, I only faced this problem in context of Git checkouts (currently in the context of https://github.com/apache/maven-scm which is a bit special as that itself deals with Git cloning in test cases)
I dislike the idea. It takes a parameter that is easy to understand and adds a bunch of conditionals behind it. Today we're going to make an exception for git. Tomorrow for what other program? This is going to catch people off-guard.
It's easier long-term to just tell people to enable force=true if they need it. A clear error message would steer people in the right direction.
I also think that creating special cases is risky. Just for exploring alternatives, what about the following?
Context: This is a Windows-only problem caused by a subtle difference in the behaviour of Unix and Windows file systems. On Windows, a read-only file is protected against both modification and deletion. On Unix, a read-only file is protected against modification only, and the protection against deletion is controlled by whether the directory is read-only.
Proposal: Instead of the default mode proposed in a previous comment, another possibility may be to introduce a posix mode meaning "behave as if it was a POSIX file system". On real Unix file system, it would be equivalent to an unconditional false. On Windows file system, it would clear the read-only file, without any check for .git or other directory.
Note 1: A posix mode would be slightly more secure than the current situation because in the current Maven Clean Plugin implementation, <force>true</force> causes the plugin to delete files even when the directory is read-only. This is stronger than what is needed for removing Git clones on Windows. With a posix mode, developers on Unix would not have their safety reduced by a project having the <force>posix</force> configuration.
Note 2: This is not really OS-dependent, but rather file system dependent. In Java code, this is determined by whether the AttributeView is actually an instance of DosFileAttributeView orPosixFileAttributeView. For example, I think that a Unix system would see an USB stick as DosFileAttributeView.
Hi,
I just want to add one opinion. As a developer, I really expect the ./target folder to disappear when I run mvn clean.
Whatever the tests create under ./target is not important β those files can always be reproduced, generated again.
Therefore, a forced delete should be the default behavior. If someone has a special use case, they should be able to configure it explicitly.
I assume that most developers share this expectation.
Best regards Imre
I assume that most developers share this expectation.
There are opinions on both sides, and we don't know which side has the majority (those who are happy with the current behaviour may not paid attention to this thread). There are also developers who think that a file marked as read-only was considered important by someone, and that it is not up to Maven to overturn this judgement.
@Krabi I'm a bit confused by the use-case you mentioned. Are you saying that you have tests that create read-only files? I agree with you that most developers would expect mvn clean to remove the target directory but at the same time I don't think that most developers create read-only files as part of their tests. I've never seen that done.
It tends to be another kind of build step (copying existing files from one place to another?) that does that.
Hello @cowwoc. My understanding of previous comment is that some peoples perform a git checkout in the target directory. Git creates a hidden .git directory with read-only files in it. I think that git wants those files to be read-only because they may be shared (with hard links) with other git checkouts. On Unix systems, this is not a problem because the read-only flag blocks only modifications of the file, not deletions. But Windows is different: on that OS, the read-only attribute blocks both modifications and deletions.
So, in my understanding of this discussion, the use case is a Windows-specific problem of users who perform git checkout in their target directory. This is understandable for testing Maven SCM for example, but I would find strange and inefficient if it was done in other contexts.
Got it. Thanks for the clarification.