diff --git a/pom.xml b/pom.xml
index 4f7a4979..4efe5984 100644
--- a/pom.xml
+++ b/pom.xml
@@ -51,7 +51,7 @@ limitations under the License.
- 6
+ 7
diff --git a/src/main/java/org/codehaus/plexus/util/FileUtils.java b/src/main/java/org/codehaus/plexus/util/FileUtils.java
old mode 100644
new mode 100755
index 8d93c9cc..7e64ac67
--- a/src/main/java/org/codehaus/plexus/util/FileUtils.java
+++ b/src/main/java/org/codehaus/plexus/util/FileUtils.java
@@ -73,6 +73,8 @@
import java.io.Writer;
import java.net.URL;
import java.nio.channels.FileChannel;
+import java.nio.file.Files;
+import java.nio.file.attribute.DosFileAttributes;
import java.security.SecureRandom;
import java.text.DecimalFormat;
import java.util.ArrayList;
@@ -1094,6 +1096,26 @@ public static void copyFile( final File source, final File destination )
private static void doCopyFile( File source, File destination )
throws IOException
{
+ // If the source file is read-only on windows, that's probably not what we want in the destination. e.g.
+ // jetty won't start if the web.xml or jetty-web.xml is read-only, for some reason. So after we copy,
+ // clear the read-only flag.
+ boolean setWriteable = Os.isFamily(Os.FAMILY_WINDOWS)
+ && source.exists()
+ && !source.canWrite()
+ && Files.readAttributes(source.toPath(), DosFileAttributes.class)
+ .isReadOnly();
+
+ // Special-case for Windows read-only file attribute on the destination file -- if it's set, unset it so
+ // that replacement of the destination doesn't fail. Files.copy will apparently not REPLACE_EXISTING in
+ // that case, at least on Windows.
+ if (Os.isFamily(Os.FAMILY_WINDOWS)
+ && destination.exists()
+ && !destination.canWrite()
+ && Files.readAttributes(destination.toPath(), DosFileAttributes.class)
+ .isReadOnly()) {
+ destination.setWritable(true);
+ }
+
// offload to operating system if supported
if ( Java7Detector.isJava7() )
{
@@ -1103,6 +1125,10 @@ private static void doCopyFile( File source, File destination )
{
doCopyFileUsingLegacyIO( source, destination );
}
+
+ if (setWriteable) {
+ destination.setWritable(true);
+ }
}
private static void doCopyFileUsingLegacyIO( File source, File destination )
diff --git a/src/test/java/org/codehaus/plexus/util/FileUtilsTest.java b/src/test/java/org/codehaus/plexus/util/FileUtilsTest.java
old mode 100644
new mode 100755
index 51087306..d68297a2
--- a/src/test/java/org/codehaus/plexus/util/FileUtilsTest.java
+++ b/src/test/java/org/codehaus/plexus/util/FileUtilsTest.java
@@ -394,6 +394,21 @@ public void testCopyFile3()
assertTrue( "Check Exist", destination.exists() );
assertTrue( "Check Full copy", destination.length() == testFile2Size );
}
+
+ public void testCopyOverReadOnlyFile()
+ throws IOException
+ {
+ final File destination = new File( getTestDirectory(), "copy2.txt" );
+
+ // Make sure file exists and is read-only
+ assertTrue(destination.createNewFile());
+ assertTrue(destination.setReadOnly());;
+
+ // Copy
+ FileUtils.copyFile( testFile1, destination );
+ assertTrue( "Check Exist", destination.exists() );
+ assertTrue( "Check Full copy", destination.length() == testFile2Size );
+ }
// copyFileIfModified