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