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); + } +}
