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

rzo1 pushed a commit to branch simple-passivater-private-dir
in repository https://gitbox.apache.org/repos/asf/tomee.git

commit aae1249f25991c19464cc0b901139b97b7fff947
Author: Richard Zowalla <[email protected]>
AuthorDate: Fri Oct 9 10:17:11 2026 +0200

    passivate stateful beans to a private temp directory by default
    
    java.io.tmpdir may be shared with other local users.
---
 .../openejb/core/stateful/SimplePassivater.java    | 14 ++-
 .../core/stateful/SimplePassivaterTest.java        | 99 ++++++++++++++++++++++
 2 files changed, 112 insertions(+), 1 deletion(-)

diff --git 
a/container/openejb-core/src/main/java/org/apache/openejb/core/stateful/SimplePassivater.java
 
b/container/openejb-core/src/main/java/org/apache/openejb/core/stateful/SimplePassivater.java
index 6ef9b6403f..02855da1f6 100644
--- 
a/container/openejb-core/src/main/java/org/apache/openejb/core/stateful/SimplePassivater.java
+++ 
b/container/openejb-core/src/main/java/org/apache/openejb/core/stateful/SimplePassivater.java
@@ -33,11 +33,19 @@ import java.io.NotSerializableException;
 import java.io.ObjectInputStream;
 import java.io.ObjectOutputStream;
 import java.io.OutputStream;
+import java.nio.file.Files;
 import java.util.Map;
 import java.util.Properties;
 
 public class SimplePassivater implements PassivationStrategy {
 
+    /**
+     * When true and no passivation directory is configured, session state is
+     * written directly into java.io.tmpdir as in previous releases instead of
+     * a private, owner-only temporary directory.
+     */
+    public static final String SHARED_TMPDIR = 
"openejb.stateful.passivation.shared-tmpdir";
+
     private static final Logger logger = 
Logger.getInstance(LogCategory.OPENEJB, "org.apache.openejb.util.resources");
     private File sessionDirectory;
 
@@ -56,8 +64,12 @@ public class SimplePassivater implements PassivationStrategy 
{
         try {
             if (dir != null) {
                 sessionDirectory = 
SystemInstance.get().getBase().getDirectory(dir);
-            } else {
+            } else if (SystemInstance.get().getOptions().get(SHARED_TMPDIR, 
false)) {
                 sessionDirectory = new 
File(JavaSecurityManagers.getSystemProperty("java.io.tmpdir", File.separator + 
"tmp"));
+            } else {
+                // created atomically and owner-only, other local users can't 
read passivated state
+                sessionDirectory = 
Files.createTempDirectory("openejb-passivation-").toFile();
+                sessionDirectory.deleteOnExit();
             }
 
             if (!sessionDirectory.exists() && !sessionDirectory.mkdirs()) {
diff --git 
a/container/openejb-core/src/test/java/org/apache/openejb/core/stateful/SimplePassivaterTest.java
 
b/container/openejb-core/src/test/java/org/apache/openejb/core/stateful/SimplePassivaterTest.java
new file mode 100644
index 0000000000..5e60cd7905
--- /dev/null
+++ 
b/container/openejb-core/src/test/java/org/apache/openejb/core/stateful/SimplePassivaterTest.java
@@ -0,0 +1,99 @@
+/*
+ * 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.apache.openejb.core.stateful;
+
+import org.apache.openejb.core.EnvProps;
+import org.apache.openejb.loader.SystemInstance;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.io.File;
+import java.lang.reflect.Field;
+import java.nio.file.Files;
+import java.nio.file.attribute.PosixFileAttributeView;
+import java.nio.file.attribute.PosixFilePermission;
+import java.util.EnumSet;
+import java.util.Properties;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertTrue;
+
+public class SimplePassivaterTest {
+
+    @Before
+    @After
+    public void reset() {
+        SystemInstance.reset();
+    }
+
+    @Test
+    public void defaultDirectoryIsPrivate() throws Exception {
+        final File dir = sessionDirectory(new SimplePassivater());
+
+        assertTrue(dir.isDirectory());
+        assertNotEquals(tmpdir(), dir.getCanonicalFile());
+        assertEquals(tmpdir(), dir.getCanonicalFile().getParentFile());
+        if 
(Files.getFileStore(dir.toPath()).supportsFileAttributeView(PosixFileAttributeView.class))
 {
+            assertEquals(EnumSet.of(PosixFilePermission.OWNER_READ, 
PosixFilePermission.OWNER_WRITE, PosixFilePermission.OWNER_EXECUTE),
+                    Files.getPosixFilePermissions(dir.toPath()));
+        }
+    }
+
+    @Test
+    public void sharedTmpdirOptOut() throws Exception {
+        SystemInstance.get().setProperty(SimplePassivater.SHARED_TMPDIR, 
"true");
+
+        assertEquals(tmpdir(), sessionDirectory(new 
SimplePassivater()).getCanonicalFile());
+    }
+
+    @Test
+    public void configuredDirectoryIsUsed() throws Exception {
+        final Properties props = new Properties();
+        props.setProperty(EnvProps.IM_PASSIVATOR_PATH_PREFIX, 
"passivation-test");
+        final SimplePassivater passivater = new SimplePassivater();
+        passivater.init(props);
+
+        final File dir = sessionDirectory(passivater);
+        try {
+            assertTrue(dir.isDirectory());
+            
assertEquals(SystemInstance.get().getBase().getDirectory("passivation-test").getCanonicalFile(),
 dir.getCanonicalFile());
+        } finally {
+            dir.delete();
+        }
+    }
+
+    @Test
+    public void passivateAndActivate() throws Exception {
+        final SimplePassivater passivater = new SimplePassivater();
+        passivater.passivate("some:key", "state");
+
+        assertTrue(new File(sessionDirectory(passivater), 
"some=key").isFile());
+        assertEquals("state", passivater.activate("some:key"));
+    }
+
+    private static File tmpdir() throws Exception {
+        return new 
File(System.getProperty("java.io.tmpdir")).getCanonicalFile();
+    }
+
+    private static File sessionDirectory(final SimplePassivater passivater) 
throws Exception {
+        final Field field = 
SimplePassivater.class.getDeclaredField("sessionDirectory");
+        field.setAccessible(true);
+        return (File) field.get(passivater);
+    }
+}

Reply via email to