diff --git a/java/org/apache/catalina/session/FileStore.java b/java/org/apache/catalina/session/FileStore.java index 0ec92f10c522..9081357992bd 100644 --- a/java/org/apache/catalina/session/FileStore.java +++ b/java/org/apache/catalina/session/FileStore.java @@ -24,6 +24,9 @@ import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; +import java.nio.file.AtomicMoveNotSupportedException; +import java.nio.file.Files; +import java.nio.file.StandardCopyOption; import java.util.ArrayList; import java.util.List; import java.util.concurrent.locks.Lock; @@ -269,13 +272,28 @@ public void save(Session session) throws IOException { .trace(sm.getString(getStoreName() + ".saving", session.getIdInternal(), file.getAbsolutePath())); } + File tempFile = new File(file.getAbsolutePath() + ".tmp"); + Lock writeLock = sessionLocksById.getLock(session.getIdInternal()).writeLock(); writeLock.lock(); try { - try (FileOutputStream fos = new FileOutputStream(file.getAbsolutePath()); + try (FileOutputStream fos = new FileOutputStream(tempFile); ObjectOutputStream oos = new ObjectOutputStream(new BufferedOutputStream(fos))) { ((StandardSession) session).writeObjectData(oos); } + try { + try { + Files.move(tempFile.toPath(), file.toPath(), StandardCopyOption.REPLACE_EXISTING, + StandardCopyOption.ATOMIC_MOVE); + } catch (AtomicMoveNotSupportedException e) { + Files.move(tempFile.toPath(), file.toPath(), StandardCopyOption.REPLACE_EXISTING); + } + } catch (IOException e) { + if (tempFile.exists() && !tempFile.delete()) { + log.warn(sm.getString("fileStore.deleteFailed", tempFile)); + } + throw e; + } } finally { writeLock.unlock(); }