This is an automated email from the ASF dual-hosted git repository.
markt-asf pushed a commit to branch 11.0.x
in repository https://gitbox.apache.org/repos/asf/tomcat.git
The following commit(s) were added to refs/heads/11.0.x by this push:
new 2ebb7588ef Ensure atomic session persistence in FileStore
2ebb7588ef is described below
commit 2ebb7588ef20a131fe65d654cdf062fe4078a217
Author: Mark Thomas <[email protected]>
AuthorDate: Wed Jun 17 08:48:43 2026 +0100
Ensure atomic session persistence in FileStore
Based on #1016 by sahvx655-wq
---
java/org/apache/catalina/session/FileStore.java | 21 +++++++++++++++++++--
webapps/docs/changelog.xml | 4 ++++
2 files changed, 23 insertions(+), 2 deletions(-)
diff --git a/java/org/apache/catalina/session/FileStore.java
b/java/org/apache/catalina/session/FileStore.java
index 0ec92f10c5..49f586bbec 100644
--- a/java/org/apache/catalina/session/FileStore.java
+++ b/java/org/apache/catalina/session/FileStore.java
@@ -24,6 +24,9 @@ import java.io.FileOutputStream;
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,15 +272,29 @@ public final class FileStore extends StoreBase {
.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 {
+ Files.move(tempFile.toPath(), file.toPath(),
StandardCopyOption.REPLACE_EXISTING,
+ StandardCopyOption.ATOMIC_MOVE);
+ } catch (AtomicMoveNotSupportedException e) {
+ Files.move(tempFile.toPath(), file.toPath(),
StandardCopyOption.REPLACE_EXISTING);
+ }
} finally {
- writeLock.unlock();
+ try {
+ if (tempFile.exists() && !tempFile.delete()) {
+ log.warn(sm.getString("fileStore.deleteFailed", tempFile));
+ }
+ } finally {
+ writeLock.unlock();
+ }
}
}
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index e96555c703..f30ff9ffef 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -307,6 +307,10 @@
<code>MemoryUserDatabase</code> to avoid concurrency issues with the
file save operations. (markt)
</fix>
+ <fix>
+ Ensure atomic session persistence in <code>FileStore</code>. Based on
+ pull request <pr>1016</pr> by sahvx655-wq. (markt)
+ </fix>
</changelog>
</subsection>
<subsection name="Coyote">
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]