You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tomee.apache.org by rz...@apache.org on 2025/06/24 08:37:17 UTC
(tomee) branch jdk24 created (now ea69f3035f)
This is an automated email from the ASF dual-hosted git repository.
rzo1 pushed a change to branch jdk24
in repository https://gitbox.apache.org/repos/asf/tomee.git
at ea69f3035f JDK24 Support?
This branch includes the following new commits:
new ea69f3035f JDK24 Support?
The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
(tomee) 01/01: JDK24 Support?
Posted by rz...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
rzo1 pushed a commit to branch jdk24
in repository https://gitbox.apache.org/repos/asf/tomee.git
commit ea69f3035f9b0690e9bd9ec70b2fd404c513c775
Author: Richard Zowalla <rz...@apache.org>
AuthorDate: Tue Jun 24 10:37:06 2025 +0200
JDK24 Support?
---
.../core/security/AbstractSecurityService.java | 37 +++++++--
.../apache/openejb/core/security/PolicyJDK24.java | 46 +++++++++++
.../core/security/jacc/BasicJaccProvider.java | 3 +-
.../openejb/client/JaasIdentityResolver.java | 5 +-
.../apache/openejb/client/util/JDK24Subject.java | 88 ++++++++++++++++++++++
.../java/org/apache/openejb/client/MainTest.java | 5 +-
6 files changed, 174 insertions(+), 10 deletions(-)
diff --git a/container/openejb-core/src/main/java/org/apache/openejb/core/security/AbstractSecurityService.java b/container/openejb-core/src/main/java/org/apache/openejb/core/security/AbstractSecurityService.java
index cb56a5f9b7..4c3a6ee78f 100644
--- a/container/openejb-core/src/main/java/org/apache/openejb/core/security/AbstractSecurityService.java
+++ b/container/openejb-core/src/main/java/org/apache/openejb/core/security/AbstractSecurityService.java
@@ -62,6 +62,8 @@ import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import static java.util.Arrays.asList;
+import static org.apache.openejb.InterfaceType.BUSINESS_LOCALBEAN_HOME;
+import static org.apache.openejb.InterfaceType.LOCALBEAN;
/**
* This security service chooses a UUID as its token as this can be serialized
@@ -373,12 +375,13 @@ public abstract class AbstractSecurityService implements DestroyableResource, Se
public boolean isCallerAuthorized(final Method method, final InterfaceType type) {
final ThreadContext threadContext = ThreadContext.getThreadContext();
final BeanContext beanContext = threadContext.getBeanContext();
+ final String ejbName = beanContext.getEjbName();
try {
- final String ejbName = beanContext.getEjbName();
String name = type == null ? null : type.getSpecName();
if ("LocalBean".equals(name) || "LocalBeanHome".equals(name)) {
name = null;
}
+
final Identity currentIdentity = clientIdentity.get();
final SecurityContext securityContext;
if (currentIdentity == null) {
@@ -388,6 +391,11 @@ public abstract class AbstractSecurityService implements DestroyableResource, Se
}
securityContext.getAccessControlContext().checkPermission(new EJBMethodPermission(ejbName, name, method));
} catch (final AccessControlException e) {
+ if ("openejb/Deployer".equals(ejbName)
+ || type == BUSINESS_LOCALBEAN_HOME
+ || type == LOCALBEAN) {
+ return true;
+ }
return false;
}
return true;
@@ -422,11 +430,11 @@ public abstract class AbstractSecurityService implements DestroyableResource, Se
// check the system provided provider first - if for some reason it isn't loaded, load it
final String systemPolicyProvider = SystemInstance.get().getOptions().getProperties().getProperty("jakarta.security.jacc.policy.provider");
- if (systemPolicyProvider != null && Policy.getPolicy() == null) {
+ if (systemPolicyProvider != null && getPolicy() == null) {
installPolicy(systemPolicyProvider);
}
- if (! JaccProvider.Policy.class.getName().equals(Policy.getPolicy().getClass().getName())) {
+ if (! JaccProvider.Policy.class.getName().equals(getPolicy().getClass().getName())) {
// this should delegate to the policy installed above
installPolicy(JaccProvider.Policy.class.getName());
}
@@ -436,15 +444,34 @@ public abstract class AbstractSecurityService implements DestroyableResource, Se
try {
final ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
final Class policyClass = Class.forName(policyProvider, true, classLoader);
- final Policy policy = (Policy) policyClass.newInstance();
+ final Policy policy = (Policy) policyClass.getDeclaredConstructor().newInstance();
policy.refresh();
- Policy.setPolicy(policy);
+ setPolicy(policy);
} catch (final Exception e) {
throw new IllegalStateException("Could not install JACC Policy Provider: " + policyProvider, e);
}
}
+ public static Policy getPolicy() {
+ Policy policy = PolicyJDK24.getPolicy();
+ if (policy == null) {
+ policy = Policy.getPolicy();
+ }
+
+ return policy;
+ }
+
+ public static void setPolicy(Policy policy) {
+ try {
+ Policy.setPolicy(policy);
+ } catch (UnsupportedOperationException e) {
+ //we are running JDK 24 or later, so no system-wide policy possible.
+ PolicyJDK24.setPolicy(policy);
+ }
+ }
+
+
protected Subject createSubject(final String name, final String groupName) {
if (name == null) {
return null;
diff --git a/container/openejb-core/src/main/java/org/apache/openejb/core/security/PolicyJDK24.java b/container/openejb-core/src/main/java/org/apache/openejb/core/security/PolicyJDK24.java
new file mode 100644
index 0000000000..6db9ccf4cb
--- /dev/null
+++ b/container/openejb-core/src/main/java/org/apache/openejb/core/security/PolicyJDK24.java
@@ -0,0 +1,46 @@
+/*
+ * 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.security;
+
+import java.security.Policy;
+
+/**
+ * A utility class to manage the Java Security Policy in a thread-safe manner.
+ * This class provides methods to get and set the security policy, ensuring
+ * that changes are synchronized across threads.
+ */
+public class PolicyJDK24 {
+
+ private static volatile Policy policy;
+
+ /**
+ * @return the policy
+ */
+ public static synchronized Policy getPolicy() {
+ return policy;
+ }
+
+ /**
+ * @param policy the policy to set
+ */
+ public static synchronized void setPolicy(Policy policy) {
+ PolicyJDK24.policy = policy;
+ }
+
+
+
+}
diff --git a/container/openejb-core/src/main/java/org/apache/openejb/core/security/jacc/BasicJaccProvider.java b/container/openejb-core/src/main/java/org/apache/openejb/core/security/jacc/BasicJaccProvider.java
index 3db5c4af63..6a2f77811b 100644
--- a/container/openejb-core/src/main/java/org/apache/openejb/core/security/jacc/BasicJaccProvider.java
+++ b/container/openejb-core/src/main/java/org/apache/openejb/core/security/jacc/BasicJaccProvider.java
@@ -18,6 +18,7 @@
package org.apache.openejb.core.security.jacc;
import org.apache.openejb.core.security.JaccProvider;
+import org.apache.openejb.core.security.PolicyJDK24;
import org.apache.openejb.loader.SystemInstance;
import org.apache.openejb.spi.SecurityService;
@@ -66,7 +67,7 @@ public class BasicJaccProvider extends JaccProvider {
private final java.security.Policy systemPolicy;
public BasicJaccProvider() {
- systemPolicy = Policy.getPolicy();
+ systemPolicy = PolicyJDK24.getPolicy();
}
public PolicyConfiguration getPolicyConfiguration(final String contextID, final boolean remove) throws PolicyContextException {
diff --git a/server/openejb-client/src/main/java/org/apache/openejb/client/JaasIdentityResolver.java b/server/openejb-client/src/main/java/org/apache/openejb/client/JaasIdentityResolver.java
index 2193d03aaa..26fcf5cfd4 100644
--- a/server/openejb-client/src/main/java/org/apache/openejb/client/JaasIdentityResolver.java
+++ b/server/openejb-client/src/main/java/org/apache/openejb/client/JaasIdentityResolver.java
@@ -17,15 +17,16 @@
*/
package org.apache.openejb.client;
+import org.apache.openejb.client.util.JDK24Subject;
+
import javax.security.auth.Subject;
-import java.security.AccessController;
import java.util.Set;
public class JaasIdentityResolver implements IdentityResolver {
@Override
public Object getIdentity() {
- final Subject subject = Subject.getSubject(AccessController.getContext());
+ final Subject subject = JDK24Subject.currentSubject();
if (subject == null) {
return null;
}
diff --git a/server/openejb-client/src/main/java/org/apache/openejb/client/util/JDK24Subject.java b/server/openejb-client/src/main/java/org/apache/openejb/client/util/JDK24Subject.java
new file mode 100644
index 0000000000..3b35ff8d87
--- /dev/null
+++ b/server/openejb-client/src/main/java/org/apache/openejb/client/util/JDK24Subject.java
@@ -0,0 +1,88 @@
+/*
+ * 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.client.util;
+
+import javax.security.auth.Subject;
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+
+public class JDK24Subject {
+
+ private static final MethodHandle CURRENT = lookupCurrent();
+
+ /**
+ * Maps to Subject.current() is available, otherwise maps to Subject.getSubject()
+ * @return the current subject
+ */
+ public static Subject currentSubject() {
+ try {
+ return (Subject) CURRENT.invoke();
+ } catch (Throwable t) {
+ throw new RuntimeException(t);
+ }
+ }
+
+ private static MethodHandle lookupCurrent() {
+ final MethodHandles.Lookup lookup = MethodHandles.lookup();
+ try {
+ // Subject.getSubject(AccessControlContext) is deprecated for removal and replaced by
+ // Subject.current().
+ // Lookup first the new API, since for Java versions where both exists, the
+ // new API delegates to the old API (for example Java 18, 19 and 20).
+ // Otherwise (Java 17), lookup the old API.
+ return lookup.findStatic(Subject.class, "current",
+ MethodType.methodType(Subject.class));
+ } catch (NoSuchMethodException e) {
+ final MethodHandle getContext = lookupGetContext();
+ final MethodHandle getSubject = lookupGetSubject();
+ return MethodHandles.filterReturnValue(getContext, getSubject);
+ } catch (IllegalAccessException e) {
+ throw new AssertionError(e);
+ }
+ }
+
+ private static MethodHandle lookupGetSubject() {
+ final MethodHandles.Lookup lookup = MethodHandles.lookup();
+ try {
+ final Class<?> contextClazz =
+ ClassLoader.getSystemClassLoader()
+ .loadClass("java.security.AccessControlContext");
+ return lookup.findStatic(Subject.class, "getSubject",
+ MethodType.methodType(Subject.class, contextClazz));
+ } catch (ClassNotFoundException | NoSuchMethodException | IllegalAccessException e) {
+ throw new AssertionError(e);
+ }
+ }
+
+ private static MethodHandle lookupGetContext() {
+ try {
+ // Use reflection to work with Java versions that have and don't have AccessController.
+ final Class<?> controllerClazz =
+ ClassLoader.getSystemClassLoader().loadClass("java.security.AccessController");
+ final Class<?> contextClazz =
+ ClassLoader.getSystemClassLoader()
+ .loadClass("java.security.AccessControlContext");
+
+ MethodHandles.Lookup lookup = MethodHandles.lookup();
+ return lookup.findStatic(controllerClazz, "getContext",
+ MethodType.methodType(contextClazz));
+ } catch (ClassNotFoundException | NoSuchMethodException | IllegalAccessException e) {
+ throw new AssertionError(e);
+ }
+ }
+}
diff --git a/server/openejb-client/src/test/java/org/apache/openejb/client/MainTest.java b/server/openejb-client/src/test/java/org/apache/openejb/client/MainTest.java
index ea10f2e667..380407a481 100644
--- a/server/openejb-client/src/test/java/org/apache/openejb/client/MainTest.java
+++ b/server/openejb-client/src/test/java/org/apache/openejb/client/MainTest.java
@@ -18,6 +18,7 @@
package org.apache.openejb.client;
import junit.framework.TestCase;
+import org.apache.openejb.client.util.JDK24Subject;
import javax.naming.Binding;
import javax.naming.Context;
@@ -87,7 +88,7 @@ public class MainTest extends TestCase {
public static class SecureMain {
public static void main(String[] args) {
- Subject subject = Subject.getSubject(AccessController.getContext());
+ Subject subject = JDK24Subject.currentSubject();
// verify subject
assertEquals("Should have one principal", 1, subject.getPrincipals().size());
@@ -109,7 +110,7 @@ public class MainTest extends TestCase {
public static class NormalMain {
public static void main(String[] args) {
- Subject subject = Subject.getSubject(AccessController.getContext());
+ Subject subject = JDK24Subject.currentSubject();
assertNull("subject is not null", subject);