This is an automated email from the ASF dual-hosted git repository.

cstamas pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/maven-resolver.git


The following commit(s) were added to refs/heads/master by this push:
     new ebe4ae437 Go back to atomic (#1594)
ebe4ae437 is described below

commit ebe4ae437fad3d4c531f09f4c0636771a99581d9
Author: Tamas Cservenak <ta...@cservenak.net>
AuthorDate: Fri Sep 19 11:41:34 2025 +0200

    Go back to atomic (#1594)
    
    This change was done due Windows, but later the execution path was split 
for Windows to use oldie pre-NIO2 code to copy as for some reason that works on 
Windows.
    
    On other platforms, insist on ATOMIC, still make use able to override it, 
in case atomic is not a viable option.
---
 .../java/org/eclipse/aether/util/FileUtils.java    | 18 +++++++--
 .../org/eclipse/aether/util/FileUtilsTest.java     | 44 ++++++++++++++++++++++
 2 files changed, 59 insertions(+), 3 deletions(-)

diff --git 
a/maven-resolver-util/src/main/java/org/eclipse/aether/util/FileUtils.java 
b/maven-resolver-util/src/main/java/org/eclipse/aether/util/FileUtils.java
index 2c0d553bf..52e2348f5 100644
--- a/maven-resolver-util/src/main/java/org/eclipse/aether/util/FileUtils.java
+++ b/maven-resolver-util/src/main/java/org/eclipse/aether/util/FileUtils.java
@@ -37,14 +37,24 @@ import static java.util.Objects.requireNonNull;
  * @since 1.9.0
  */
 public final class FileUtils {
-    // Logic borrowed from Commons-Lang3: we really need only this, to decide 
do we "atomic move" or not
+    /**
+     * Logic borrowed from Commons-Lang3: we really need only this, to decide 
do we NIO2 file ops or not.
+     * For some reason non-NIO2 works better on Windows.
+     */
     private static final boolean IS_WINDOWS =
             System.getProperty("os.name", "unknown").startsWith("Windows");
 
+    /**
+     * Escape hatch if atomic move is not desired on system we run on.
+     *
+     * @since 2.0.12
+     */
+    private static final boolean ATOMIC_MOVE =
+            Boolean.parseBoolean(System.getProperty(FileUtils.class.getName() 
+ "ATOMIC_MOVE", "true"));
+
     private FileUtils() {
         // hide constructor
     }
-
     /**
      * A temporary file, that is removed when closed.
      */
@@ -115,6 +125,8 @@ public final class FileUtils {
                 + 
Long.toUnsignedString(ThreadLocalRandom.current().nextLong()) + ".tmp");
         return new CollocatedTempFile() {
             private final AtomicBoolean wantsMove = new AtomicBoolean(false);
+            private final StandardCopyOption copyOption =
+                    FileUtils.ATOMIC_MOVE ? StandardCopyOption.ATOMIC_MOVE : 
StandardCopyOption.REPLACE_EXISTING;
 
             @Override
             public Path getPath() {
@@ -132,7 +144,7 @@ public final class FileUtils {
                     if (IS_WINDOWS) {
                         copy(tempFile, file);
                     } else {
-                        Files.move(tempFile, file, 
StandardCopyOption.REPLACE_EXISTING);
+                        Files.move(tempFile, file, copyOption);
                     }
                 }
                 Files.deleteIfExists(tempFile);
diff --git 
a/maven-resolver-util/src/test/java/org/eclipse/aether/util/FileUtilsTest.java 
b/maven-resolver-util/src/test/java/org/eclipse/aether/util/FileUtilsTest.java
new file mode 100644
index 000000000..e4ad14c31
--- /dev/null
+++ 
b/maven-resolver-util/src/test/java/org/eclipse/aether/util/FileUtilsTest.java
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.eclipse.aether.util;
+
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.io.TempDir;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+public class FileUtilsTest {
+    @Test
+    void smoke(@TempDir Path tmp) throws IOException {
+        Path target = tmp.resolve("target.txt");
+        Files.write(target, "Hello world".getBytes(StandardCharsets.UTF_8));
+        assertEquals("Hello world", new String(Files.readAllBytes(target), 
StandardCharsets.UTF_8));
+
+        try (FileUtils.CollocatedTempFile tempFile = 
FileUtils.newTempFile(target)) {
+            Files.write(tempFile.getPath(), "Hello other 
world".getBytes(StandardCharsets.UTF_8));
+            tempFile.move();
+        }
+        assertEquals("Hello other world", new 
String(Files.readAllBytes(target), StandardCharsets.UTF_8));
+    }
+}

Reply via email to