diff --git a/maven-artifact/src/main/java/org/apache/maven/artifact/manager/DefaultWagonManager.java b/maven-artifact/src/main/java/org/apache/maven/artifact/manager/DefaultWagonManager.java index 8a7c9fad79..9e3cd781bc 100644 --- a/maven-artifact/src/main/java/org/apache/maven/artifact/manager/DefaultWagonManager.java +++ b/maven-artifact/src/main/java/org/apache/maven/artifact/manager/DefaultWagonManager.java @@ -31,12 +31,14 @@ import org.apache.maven.wagon.authorization.AuthorizationException; import org.apache.maven.wagon.observers.ChecksumObserver; import org.codehaus.plexus.PlexusConstants; import org.codehaus.plexus.PlexusContainer; +import org.codehaus.plexus.util.FileUtils; import org.codehaus.plexus.component.repository.exception.ComponentLookupException; import org.codehaus.plexus.context.Context; import org.codehaus.plexus.context.ContextException; import org.codehaus.plexus.personality.plexus.lifecycle.phase.Contextualizable; import java.io.File; +import java.io.IOException; import java.util.Iterator; import java.util.Set; @@ -134,7 +136,7 @@ public class DefaultWagonManager try { - temp = File.createTempFile( "wagon", "tmp" ); + temp = new File( destination + ".tmp" ); temp.deleteOnExit(); } @@ -149,7 +151,6 @@ public class DefaultWagonManager try { - Wagon wagon = getWagon( repository.getProtocol() ); // ---------------------------------------------------------------------- @@ -165,8 +166,6 @@ public class DefaultWagonManager wagon.get( path( artifact ), temp ); - transfered = true; - wagon.disconnect(); releaseWagon( wagon ); @@ -176,6 +175,8 @@ public class DefaultWagonManager { // This one we will eat when looking through remote repositories // because we want to cycle through them all before squawking. + + continue; } catch ( UnsupportedProtocolException e ) { @@ -197,25 +198,36 @@ public class DefaultWagonManager { throw new TransferFailedException( "Release of wagon failed: ", e ); } - } - if ( transfered ) - { if ( !destination.getParentFile().exists() ) { destination.getParentFile().mkdirs(); } - transfered = temp.renameTo( destination ); + // The temporary file is named destination + ".tmp" and is done this way to ensure + // that the temporary file is in the same file system as the destination because the + // File.renameTo operation doesn't really work across file systems. So we will attempt + // to do a File.renameTo for efficiency and atomicity, if this fails then we will use + // a brute force copy and delete the temporary file. + + if ( !temp.renameTo( destination ) ) + { + try + { + FileUtils.copyFile( temp, destination ); + + temp.delete(); + } + catch ( IOException e ) + { + throw new TransferFailedException( "Error copying temporary file to the final destination: ", e ); + } + } return; } - else - { - temp.delete(); - throw new TransferFailedException( "Resource doesn't exist in any remote repository" ); - } + throw new TransferFailedException( "Resource doesn't exist in any remote repository" ); } public void contextualize( Context context )