From 145f25d82c99796693e56c6bf18905241494d7aa Mon Sep 17 00:00:00 2001 From: Holger Friedrich Date: Sat, 27 Dec 2025 14:09:44 +0100 Subject: [PATCH 1/5] Lift minimum JDK version to 21 and remove SecurityManager * Lift minimum JDK version to 21 * Remove occurrences of SecurityManager, as getSecurityManager returns null since JDK 18 * Enable verbose deprecation warnings * Replace getSubject and doAs calls, getSubject can no longer be activated via JRE command line as SecurityManager has been removed in JDK 25. A replacement is available since Java 21. doAs was deprecated and is replaced by callAll. * Remove SecurityManager form JavaSecurityTest --- .github/workflows/ci.yml | 8 +-- .../resources/archetype-resources/pom.xml | 2 +- .../resources/archetype-resources/pom.xml | 5 +- archetypes/bundle/pom.xml | 5 +- .../resources/archetype-resources/pom.xml | 5 +- .../resources/archetype-resources/pom.xml | 5 +- assemblies/apache-karaf-minimal/pom.xml | 2 +- assemblies/apache-karaf-mix/pom.xml | 2 +- assemblies/apache-karaf/pom.xml | 2 +- .../main/filtered-resources/resources/bin/inc | 6 --- .../resources/bin/karaf.bat | 4 -- assemblies/features/enterprise/pom.xml | 2 +- assemblies/features/integration/pom.xml | 2 +- assemblies/features/specs/pom.xml | 4 +- assemblies/features/spring/pom.xml | 2 +- assemblies/features/standard/pom.xml | 2 +- .../karaf-docker-example-dynamic-dist/pom.xml | 4 +- .../karaf-docker-example-static-dist/pom.xml | 2 +- .../karaf-graphql-example-websocket/pom.xml | 4 +- .../core/internal/InstanceServiceImpl.java | 3 -- .../apache/karaf/itests/KarafTestSupport.java | 3 +- .../apache/karaf/itests/JavaSecurityTest.java | 3 -- .../karaf/jaas/command/WhoamiCommand.java | 3 +- .../modules/ldap/GSSAPILdapLoginModule.java | 6 ++- .../apache/karaf/main/MainLockingTest.java | 30 +++++------ .../internal/BulkRequestContext.java | 11 ++-- .../management/KarafMBeanServerGuardTest.java | 54 +++++++++---------- pom.xml | 17 ++++-- .../guard/impl/GuardProxyCatalogTest.java | 26 ++++----- .../impl/handler/EventAdminImpl.java | 2 +- .../impl/SecuredCommandProcessorImpl.java | 3 +- .../apache/karaf/shell/util/ShellUtil.java | 3 +- .../secured/SecuredSessionFactoryImpl.java | 6 +-- .../apache/karaf/shell/support/ShellUtil.java | 3 +- tooling/karaf-maven-plugin/pom.xml | 3 +- .../src/it/test-aggregate-features/pom.xml | 2 - .../src/it/test-basic-generation/pom.xml | 2 - .../test-check-dependencies-failure/pom.xml | 2 - .../src/it/test-check-dependencies/pom.xml | 2 - .../src/it/test-feature-dependencies/pom.xml | 2 - .../transitive/pom.xml | 2 - .../it/test-include-project-artifact/pom.xml | 2 - .../src/it/test-input-file/pom.xml | 2 - .../src/it/test-recursive/pom.xml | 2 - .../src/it/test-rename-main-feature/pom.xml | 2 - .../it/test-repository-dependencies/pom.xml | 2 - .../src/it/test-run-bundle/pom.xml | 2 - .../src/it/test-simplify-bundles/pom.xml | 2 - .../it/test-transitive-as-dependency/pom.xml | 2 - .../src/it/test-type-classifier/pom.xml | 2 - .../org/apache/karaf/util/ThreadUtils.java | 3 +- .../apache/karaf/util/jaas/JaasHelper.java | 6 +-- .../karaf/util/tracker/BaseActivator.java | 3 +- .../karaf/webconsole/gogo/GogoPlugin.java | 3 +- 54 files changed, 117 insertions(+), 172 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index bc0f0024d70..dab7d6945a3 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -42,10 +42,10 @@ jobs: steps: - name: Checkout uses: actions/checkout@v7 - - name: Set up JDK 17 + - name: Set up JDK 21 uses: actions/setup-java@v5 with: - java-version: '17' + java-version: '21' distribution: 'temurin' cache: 'maven' - name: Build @@ -74,10 +74,10 @@ jobs: steps: - name: Checkout uses: actions/checkout@v7 - - name: Set up JDK 17 + - name: Set up JDK 21 uses: actions/setup-java@v5 with: - java-version: '17' + java-version: '21' distribution: 'temurin' cache: 'maven' - name: Restore Maven Local Repository diff --git a/archetypes/assembly/src/main/resources/archetype-resources/pom.xml b/archetypes/assembly/src/main/resources/archetype-resources/pom.xml index 4bd78a8db18..d8f83f8bffb 100644 --- a/archetypes/assembly/src/main/resources/archetype-resources/pom.xml +++ b/archetypes/assembly/src/main/resources/archetype-resources/pom.xml @@ -174,7 +174,7 @@ - 17 + 21 diff --git a/archetypes/blueprint/src/main/resources/archetype-resources/pom.xml b/archetypes/blueprint/src/main/resources/archetype-resources/pom.xml index d442fecc346..cd322ff1458 100644 --- a/archetypes/blueprint/src/main/resources/archetype-resources/pom.xml +++ b/archetypes/blueprint/src/main/resources/archetype-resources/pom.xml @@ -63,8 +63,9 @@ maven-compiler-plugin 3.15.0 - 1.8 - 1.8 + 21 + 21 + 21 256M diff --git a/archetypes/bundle/pom.xml b/archetypes/bundle/pom.xml index 3bbc2cecbac..0cb6128f97a 100644 --- a/archetypes/bundle/pom.xml +++ b/archetypes/bundle/pom.xml @@ -57,8 +57,9 @@ org.apache.maven.plugins maven-compiler-plugin - 1.8 - 1.8 + 21 + 21 + 21 256M diff --git a/archetypes/bundle/src/main/resources/archetype-resources/pom.xml b/archetypes/bundle/src/main/resources/archetype-resources/pom.xml index 798beaeab16..83654cd8942 100644 --- a/archetypes/bundle/src/main/resources/archetype-resources/pom.xml +++ b/archetypes/bundle/src/main/resources/archetype-resources/pom.xml @@ -82,8 +82,9 @@ maven-compiler-plugin 3.15.0 - 1.8 - 1.8 + 21 + 21 + 21 256M diff --git a/archetypes/command/src/main/resources/archetype-resources/pom.xml b/archetypes/command/src/main/resources/archetype-resources/pom.xml index 73ab71c704b..6a579d1cc27 100644 --- a/archetypes/command/src/main/resources/archetype-resources/pom.xml +++ b/archetypes/command/src/main/resources/archetype-resources/pom.xml @@ -67,8 +67,9 @@ true 3.15.0 - 1.8 - 1.8 + 21 + 21 + 21 diff --git a/assemblies/apache-karaf-minimal/pom.xml b/assemblies/apache-karaf-minimal/pom.xml index 072afd67715..481bbedd666 100644 --- a/assemblies/apache-karaf-minimal/pom.xml +++ b/assemblies/apache-karaf-minimal/pom.xml @@ -145,7 +145,7 @@ !org.apache.karaf.command.acl.*, * - 17 + 21 diff --git a/assemblies/apache-karaf-mix/pom.xml b/assemblies/apache-karaf-mix/pom.xml index e07eec0e8bf..0dad89e8c71 100644 --- a/assemblies/apache-karaf-mix/pom.xml +++ b/assemblies/apache-karaf-mix/pom.xml @@ -187,7 +187,7 @@ - 17 + 21 ${project.build.directory} Apache Karaf Mix diff --git a/assemblies/apache-karaf/pom.xml b/assemblies/apache-karaf/pom.xml index 9c05670f68f..60dd7a90911 100644 --- a/assemblies/apache-karaf/pom.xml +++ b/assemblies/apache-karaf/pom.xml @@ -178,7 +178,7 @@ - 17 + 21 ${project.build.directory} Apache Karaf (full) diff --git a/assemblies/features/base/src/main/filtered-resources/resources/bin/inc b/assemblies/features/base/src/main/filtered-resources/resources/bin/inc index 2809e8be7cf..004142ab4ba 100644 --- a/assemblies/features/base/src/main/filtered-resources/resources/bin/inc +++ b/assemblies/features/base/src/main/filtered-resources/resources/bin/inc @@ -282,12 +282,6 @@ setupVendorSepcifics() { setupDefaults() { DEFAULT_JAVA_OPTS="-XX:+UnlockDiagnosticVMOptions " - if [ "${VERSION}" -gt "11" ]; then - # TODO revisit EventAdminImpl to avoid use of Subject.getSubject(AccessController.getContext()); - # -Djava.security.manager=allow is a workaround for SecurityController deprecation in JDK23+ - DEFAULT_JAVA_OPTS="$DEFAULT_JAVA_OPTS -Djava.security.manager=allow " - fi - setupVendorSepcifics DEFAULT_JAVA_OPTS="${DEFAULT_JAVA_OPTS} ${JAVA_VENDOR_OPTS}" diff --git a/assemblies/features/base/src/main/filtered-resources/resources/bin/karaf.bat b/assemblies/features/base/src/main/filtered-resources/resources/bin/karaf.bat index 0be0d7df37e..8f6a88694f1 100644 --- a/assemblies/features/base/src/main/filtered-resources/resources/bin/karaf.bat +++ b/assemblies/features/base/src/main/filtered-resources/resources/bin/karaf.bat @@ -267,10 +267,6 @@ if not exist "%JAVA_HOME%\bin\server\jvm.dll" ( ) set DEFAULT_JAVA_OPTS=-XX:+UnlockDiagnosticVMOptions -if "%JAVA_VERSION%" GTR 11 ( - set DEFAULT_JAVA_OPTS=%DEFAULT_JAVA_OPTS% -Djava.security.manager=allow -) - if "%JAVA_OPTS%" == "" set JAVA_OPTS=%DEFAULT_JAVA_OPTS% if "%EXTRA_JAVA_OPTS%" == "" goto :KARAF_EXTRA_JAVA_OPTS_END diff --git a/assemblies/features/enterprise/pom.xml b/assemblies/features/enterprise/pom.xml index 5ff00a0b820..281a0c4d0ee 100644 --- a/assemblies/features/enterprise/pom.xml +++ b/assemblies/features/enterprise/pom.xml @@ -214,7 +214,7 @@ file:${project.build.directory}/feature/feature.xml org.apache.karaf.features:framework - 17 + 21 framework diff --git a/assemblies/features/integration/pom.xml b/assemblies/features/integration/pom.xml index 54faea9360a..a4ec1f608c5 100644 --- a/assemblies/features/integration/pom.xml +++ b/assemblies/features/integration/pom.xml @@ -105,7 +105,7 @@ file:${project.build.directory}/feature/feature.xml org.apache.karaf.features:framework - 17 + 21 framework diff --git a/assemblies/features/specs/pom.xml b/assemblies/features/specs/pom.xml index 5944e6081b3..36ba1df5130 100644 --- a/assemblies/features/specs/pom.xml +++ b/assemblies/features/specs/pom.xml @@ -96,7 +96,7 @@ file:${project.build.directory}/feature/feature.xml org.apache.karaf.features:framework - 17 + 21 framework @@ -149,4 +149,4 @@ - \ No newline at end of file + diff --git a/assemblies/features/spring/pom.xml b/assemblies/features/spring/pom.xml index b5abe0e26ad..c04a2ca250c 100644 --- a/assemblies/features/spring/pom.xml +++ b/assemblies/features/spring/pom.xml @@ -158,7 +158,7 @@ file:${project.build.directory}/feature/feature.xml org.apache.karaf.features:framework - 17 + 21 framework diff --git a/assemblies/features/standard/pom.xml b/assemblies/features/standard/pom.xml index 540a5919c4d..c04f77a77b3 100644 --- a/assemblies/features/standard/pom.xml +++ b/assemblies/features/standard/pom.xml @@ -476,7 +476,7 @@ file:${project.build.directory}/feature/feature.xml org.apache.karaf.features:framework - 17 + 21 framework diff --git a/examples/karaf-docker-example/karaf-docker-example-dynamic-dist/pom.xml b/examples/karaf-docker-example/karaf-docker-example-dynamic-dist/pom.xml index 0d444b96cfc..729a495cc3e 100644 --- a/examples/karaf-docker-example/karaf-docker-example-dynamic-dist/pom.xml +++ b/examples/karaf-docker-example/karaf-docker-example-dynamic-dist/pom.xml @@ -138,7 +138,7 @@ - 17 + 21 @@ -194,4 +194,4 @@ - \ No newline at end of file + diff --git a/examples/karaf-docker-example/karaf-docker-example-static-dist/pom.xml b/examples/karaf-docker-example/karaf-docker-example-static-dist/pom.xml index 6113f130090..dbc715cc36d 100644 --- a/examples/karaf-docker-example/karaf-docker-example-static-dist/pom.xml +++ b/examples/karaf-docker-example/karaf-docker-example-static-dist/pom.xml @@ -108,7 +108,7 @@ static true static - 17 + 21 diff --git a/examples/karaf-graphql-example/karaf-graphql-example-websocket/pom.xml b/examples/karaf-graphql-example/karaf-graphql-example-websocket/pom.xml index c684882f738..61817c99136 100644 --- a/examples/karaf-graphql-example/karaf-graphql-example-websocket/pom.xml +++ b/examples/karaf-graphql-example/karaf-graphql-example-websocket/pom.xml @@ -70,8 +70,8 @@ org.apache.maven.plugins maven-compiler-plugin - 11 - 11 + 21 + 21 diff --git a/instance/src/main/java/org/apache/karaf/instance/core/internal/InstanceServiceImpl.java b/instance/src/main/java/org/apache/karaf/instance/core/internal/InstanceServiceImpl.java index e99d07c0e7c..f208e8e59a4 100644 --- a/instance/src/main/java/org/apache/karaf/instance/core/internal/InstanceServiceImpl.java +++ b/instance/src/main/java/org/apache/karaf/instance/core/internal/InstanceServiceImpl.java @@ -533,9 +533,6 @@ private static void doStart(InstanceState instance, String name, String javaOpts " --add-exports=jdk.naming.rmi/com.sun.jndi.url.rmi=ALL-UNNAMED" + " --add-exports=java.security.sasl/com.sun.security.sasl=ALL-UNNAMED" + " --add-exports=java.naming/com.sun.jndi.ldap=ALL-UNNAMED"; - if (!System.getProperty("java.version").startsWith("11")) { - jdkOpts += " -Djava.security.manager=allow"; - } } else { jdkOpts = " -Djava.endorsed.dirs=\"" + new File(new File(new File(System.getProperty("java.home"), "jre"), "lib"), "endorsed") + System.getProperty("path.separator") + new File(new File(System.getProperty("java.home"), "lib"), "endorsed") + "\"" + " -Djava.ext.dirs=\"" + new File(new File(new File(System.getProperty("java.home"), "jre"), "lib"), "ext") + System.getProperty("path.separator") + new File(new File(System.getProperty("java.home"), "lib"), "ext") + System.getProperty("path.separator") + new File(libDir, "ext").getCanonicalPath() + "\""; diff --git a/itests/common/src/main/java/org/apache/karaf/itests/KarafTestSupport.java b/itests/common/src/main/java/org/apache/karaf/itests/KarafTestSupport.java index 3a9876d12b0..c0203a4b993 100644 --- a/itests/common/src/main/java/org/apache/karaf/itests/KarafTestSupport.java +++ b/itests/common/src/main/java/org/apache/karaf/itests/KarafTestSupport.java @@ -25,7 +25,6 @@ import java.nio.file.Path; import java.nio.file.Paths; import java.security.Principal; -import java.security.PrivilegedExceptionAction; import java.util.Arrays; import java.util.Collection; import java.util.Collections; @@ -421,7 +420,7 @@ private String executeCommand(final String command, final Long timeout, final Lo commandFuture = new FutureTask<>(() -> { Subject subject = new Subject(); subject.getPrincipals().addAll(Arrays.asList(principals)); - return Subject.doAs(subject, (PrivilegedExceptionAction) commandCallable::call); + return Subject.callAs(subject, (Callable) commandCallable::call); }); } diff --git a/itests/test/src/test/java/org/apache/karaf/itests/JavaSecurityTest.java b/itests/test/src/test/java/org/apache/karaf/itests/JavaSecurityTest.java index 009a9e436d3..2d6459b0a6b 100644 --- a/itests/test/src/test/java/org/apache/karaf/itests/JavaSecurityTest.java +++ b/itests/test/src/test/java/org/apache/karaf/itests/JavaSecurityTest.java @@ -34,7 +34,6 @@ import java.nio.file.StandardCopyOption; import java.util.*; -import static org.junit.Assert.assertNotNull; import static org.junit.Assert.fail; import static org.ops4j.pax.exam.CoreOptions.maven; import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.*; @@ -72,8 +71,6 @@ public Option[] config() { @Test public void testJavaSecurity() throws Exception { - assertNotNull("Karaf should run under a security manager", System.getSecurityManager()); - BundleService service = getOsgiService(BundleService.class); long tried = 0; while (true) { diff --git a/jaas/command/src/main/java/org/apache/karaf/jaas/command/WhoamiCommand.java b/jaas/command/src/main/java/org/apache/karaf/jaas/command/WhoamiCommand.java index 3ce1e5dc6df..c587f166ed5 100644 --- a/jaas/command/src/main/java/org/apache/karaf/jaas/command/WhoamiCommand.java +++ b/jaas/command/src/main/java/org/apache/karaf/jaas/command/WhoamiCommand.java @@ -55,8 +55,7 @@ public Object execute() throws Exception { ShellTable table = new ShellTable(); // Get the currently-active JAAS Subject. - AccessControlContext acc = AccessController.getContext(); - Subject subj = Subject.getSubject(acc); + Subject subj = Subject.current(); String classString = USER_CLASS; if (groups) { diff --git a/jaas/modules/src/main/java/org/apache/karaf/jaas/modules/ldap/GSSAPILdapLoginModule.java b/jaas/modules/src/main/java/org/apache/karaf/jaas/modules/ldap/GSSAPILdapLoginModule.java index 2c911765529..dd365e0fa05 100644 --- a/jaas/modules/src/main/java/org/apache/karaf/jaas/modules/ldap/GSSAPILdapLoginModule.java +++ b/jaas/modules/src/main/java/org/apache/karaf/jaas/modules/ldap/GSSAPILdapLoginModule.java @@ -34,6 +34,8 @@ import java.util.HashMap; import java.util.HashSet; import java.util.Map; +import java.util.concurrent.Callable; +import java.util.concurrent.CompletionException; /** * Specific LDAPLoginModule to be used with GSSAPI. Uses the specified realm as login context. @@ -62,9 +64,9 @@ public boolean login() throws LoginException { context.login(); try { - succeeded = Subject.doAs(context.getSubject(), (PrivilegedExceptionAction) this::doLogin); + succeeded = Subject.callAs(context.getSubject(), (Callable) this::doLogin); return succeeded; - } catch (PrivilegedActionException pExcp) { + } catch (CompletionException pExcp) { logger.error("error with delegated authentication", pExcp); throw new LoginException(pExcp.getMessage()); } diff --git a/main/src/test/java/org/apache/karaf/main/MainLockingTest.java b/main/src/test/java/org/apache/karaf/main/MainLockingTest.java index ac01543343c..d1beb601343 100644 --- a/main/src/test/java/org/apache/karaf/main/MainLockingTest.java +++ b/main/src/test/java/org/apache/karaf/main/MainLockingTest.java @@ -38,6 +38,16 @@ public class MainLockingTest { private File data; private File log; + private Bundle installTimeoutShutdownBundle(Framework framework) throws Exception { + return framework.getBundleContext().installBundle("foo", + TinyBundles.bundle() + .addClass(TimeoutShutdownActivator.class) + .setHeader(Constants.BUNDLE_ACTIVATOR, TimeoutShutdownActivator.class.getName()) + .setHeader(Constants.IMPORT_PACKAGE, "org.osgi.framework") + .build(TinyBundles.bndBuilder()) + ); + } + @Before public void setUp() throws IOException { File basedir = new File(getClass().getClassLoader().getResource("foo").getPath()).getParentFile(); @@ -82,12 +92,7 @@ public void testLostMasterLock() throws Exception { Main main = new Main(args); main.launch(); Framework framework = main.getFramework(); - Bundle bundle = framework.getBundleContext().installBundle("foo", - TinyBundles.bundle() - .addClass(TimeoutShutdownActivator.class) - .setHeader(Constants.BUNDLE_ACTIVATOR, TimeoutShutdownActivator.class.getName()) - .build(TinyBundles.bndBuilder()) - ); + Bundle bundle = installTimeoutShutdownBundle(framework); bundle.start(); @@ -127,12 +132,7 @@ public void testRetainsMasterLockOverFluctuation() throws Exception { Main main = new Main(args); main.launch(); Framework framework = main.getFramework(); - Bundle bundle = framework.getBundleContext().installBundle("foo", - TinyBundles.bundle() - .setHeader(Constants.BUNDLE_ACTIVATOR, TimeoutShutdownActivator.class.getName()) - .addClass(TimeoutShutdownActivator.class) - .build(TinyBundles.bndBuilder()) - ); + Bundle bundle = installTimeoutShutdownBundle(framework); bundle.start(); @@ -172,11 +172,7 @@ public void testLostMasterLockAfterThreshold() throws Exception { Main main = new Main(args); main.launch(); Framework framework = main.getFramework(); - Bundle bundle = framework.getBundleContext().installBundle("foo", - TinyBundles.bundle() - .setHeader(Constants.BUNDLE_ACTIVATOR, TimeoutShutdownActivator.class.getName()) - .addClass(TimeoutShutdownActivator.class) - .build(TinyBundles.bndBuilder())); + Bundle bundle = installTimeoutShutdownBundle(framework); bundle.start(); diff --git a/management/server/src/main/java/org/apache/karaf/management/internal/BulkRequestContext.java b/management/server/src/main/java/org/apache/karaf/management/internal/BulkRequestContext.java index 7d1e0641e80..ce6f8f796cb 100644 --- a/management/server/src/main/java/org/apache/karaf/management/internal/BulkRequestContext.java +++ b/management/server/src/main/java/org/apache/karaf/management/internal/BulkRequestContext.java @@ -63,16 +63,11 @@ public static BulkRequestContext newContext(ConfigurationAdmin configAdmin) thro context.configAdmin = configAdmin; try { // check JAAS subject here - AccessControlContext acc = AccessController.getContext(); - if (acc == null) { + Subject subject = Subject.current(); + if (subject == null) { context.anonymous = true; } else { - Subject subject = Subject.getSubject(acc); - if (subject == null) { - context.anonymous = true; - } else { - context.principals.addAll(subject.getPrincipals()); - } + context.principals.addAll(subject.getPrincipals()); } // list available ACL configs - valid for this instance only for (Configuration config : configAdmin.listConfigurations("(service.pid=jmx.acl*)")) { diff --git a/management/server/src/test/java/org/apache/karaf/management/KarafMBeanServerGuardTest.java b/management/server/src/test/java/org/apache/karaf/management/KarafMBeanServerGuardTest.java index 0165ceba3e7..d74354d81d0 100644 --- a/management/server/src/test/java/org/apache/karaf/management/KarafMBeanServerGuardTest.java +++ b/management/server/src/test/java/org/apache/karaf/management/KarafMBeanServerGuardTest.java @@ -33,8 +33,8 @@ import java.io.IOException; import java.lang.reflect.Method; import java.security.Principal; -import java.security.PrivilegedAction; import java.util.*; +import java.util.concurrent.Callable; public class KarafMBeanServerGuardTest extends TestCase { @@ -462,7 +462,7 @@ private static ConfigurationAdmin getMockConfigAdmin2(Dictionary public void testCurrentUserHasRole() throws Exception { Subject subject = loginWithTestRoles("test"); - Subject.doAs(subject, (PrivilegedAction) () -> { + Subject.callAs(subject, (Callable) () -> { assertTrue(JaasHelper.currentUserHasRole("test")); assertFalse(JaasHelper.currentUserHasRole("toast")); return null; @@ -476,7 +476,7 @@ public void testCurrentUserHasCustomRole() throws Exception { lm.login(); lm.commit(); - Subject.doAs(subject, (PrivilegedAction) () -> { + Subject.callAs(subject, (Callable) () -> { assertTrue(JaasHelper.currentUserHasRole(TestRolePrincipal.class.getCanonicalName() + ":foo")); assertFalse(JaasHelper.currentUserHasRole("foo")); return null; @@ -493,7 +493,7 @@ public void testInvoke() throws Throwable { guard.setConfigAdmin(ca); Subject subject = loginWithTestRoles("editor", "admin"); - Subject.doAs(subject, (PrivilegedAction) () -> { + Subject.callAs(subject, (Callable) () -> { try { Method im = MBeanServer.class.getMethod("invoke", ObjectName.class, String.class, Object[].class, String[].class); @@ -547,7 +547,7 @@ public void testGetAttributeIs() throws Throwable { guard.setConfigAdmin(ca); Subject subject = loginWithTestRoles("editor", "admin"); - Subject.doAs(subject, (PrivilegedAction) () -> { + Subject.callAs(subject, (Callable) () -> { try { Method im = MBeanServer.class.getMethod("getAttribute", ObjectName.class, String.class); @@ -593,7 +593,7 @@ public void testGetAttributes() throws Throwable { guard.setConfigAdmin(ca); Subject subject = loginWithTestRoles("editor", "admin"); - Subject.doAs(subject, (PrivilegedAction) () -> { + Subject.callAs(subject, (Callable) () -> { try { Method im = MBeanServer.class.getMethod("getAttributes", ObjectName.class, String[].class); @@ -641,7 +641,7 @@ public void testGetAttributes2() throws Throwable { guard.setConfigAdmin(ca); Subject subject = loginWithTestRoles("editor", "admin"); - Subject.doAs(subject, (PrivilegedAction) () -> { + Subject.callAs(subject, (Callable) () -> { try { Method im = MBeanServer.class.getMethod("getAttributes", ObjectName.class, String[].class); @@ -688,7 +688,7 @@ public void testSetAttribute() throws Throwable { guard.setConfigAdmin(ca); Subject subject = loginWithTestRoles("editor", "admin"); - Subject.doAs(subject, (PrivilegedAction) () -> { + Subject.callAs(subject, (Callable) () -> { try { Method im = MBeanServer.class.getMethod("setAttribute", ObjectName.class, Attribute.class); @@ -742,7 +742,7 @@ public void testSetAttributes() throws Throwable { guard.setConfigAdmin(ca); Subject subject = loginWithTestRoles("editor", "admin"); - Subject.doAs(subject, (PrivilegedAction) () -> { + Subject.callAs(subject, (Callable) () -> { try { Method im = MBeanServer.class.getMethod("setAttributes", ObjectName.class, AttributeList.class); @@ -810,7 +810,7 @@ public void testCanInvokeMBean() throws Exception { Subject subject = loginWithTestRoles("viewer"); - Subject.doAs(subject, (PrivilegedAction) () -> { + Subject.callAs(subject, (Callable) () -> { try { assertTrue(guard.canInvoke(mbs, on)); assertFalse(guard.canInvoke(mbs, on2)); @@ -851,7 +851,7 @@ public void testCanInvokeMBean2() throws Exception { Subject subject = loginWithTestRoles("viewer"); - Subject.doAs(subject, (PrivilegedAction) () -> { + Subject.callAs(subject, (Callable) () -> { try { assertFalse(guard.canInvoke(mbs, on)); @@ -889,7 +889,7 @@ public void testCanInvokeAnyOverload() throws Exception { guard.setConfigAdmin(ca); Subject subject = loginWithTestRoles("viewer"); - Subject.doAs(subject, (PrivilegedAction) () -> { + Subject.callAs(subject, (Callable) () -> { try { assertTrue(guard.canInvoke(mbs, on, "doit")); @@ -928,7 +928,7 @@ public void testCanInvokeAnyOverload2() throws Exception { guard.setConfigAdmin(ca); Subject subject = loginWithTestRoles("viewer"); - Subject.doAs(subject, (PrivilegedAction) () -> { + Subject.callAs(subject, (Callable) () -> { try { assertFalse(guard.canInvoke(mbs, on, "doit")); @@ -960,7 +960,7 @@ public void testCanInvokeAnyOverload3() throws Exception { guard.setConfigAdmin(ca); Subject subject = loginWithTestRoles("viewer"); - Subject.doAs(subject, (PrivilegedAction) () -> { + Subject.callAs(subject, (Callable) () -> { try { assertFalse(guard.canInvoke(mbs, on, "doit")); @@ -994,7 +994,7 @@ public void testCanGetAttributeAnyOverload() throws Exception { guard.setConfigAdmin(ca); Subject subject = loginWithTestRoles("viewer"); - Subject.doAs(subject, (PrivilegedAction) () -> { + Subject.callAs(subject, (Callable) () -> { try { assertTrue(guard.canInvoke(mbs, on, "getFoo")); @@ -1028,7 +1028,7 @@ public void testCanGetAttributeAnyOverload2() throws Exception { guard.setConfigAdmin(ca); Subject subject = loginWithTestRoles("viewer"); - Subject.doAs(subject, (PrivilegedAction) () -> { + Subject.callAs(subject, (Callable) () -> { try { assertFalse(guard.canInvoke(mbs, on, "getFoo")); @@ -1063,7 +1063,7 @@ public void testCanGetAttributeAnyOverload3() throws Exception { guard.setConfigAdmin(ca); Subject subject = loginWithTestRoles("viewer"); - Subject.doAs(subject, (PrivilegedAction) () -> { + Subject.callAs(subject, (Callable) () -> { try { assertTrue(guard.canInvoke(mbs, on, "isFoo")); @@ -1098,7 +1098,7 @@ public void testCanGetAttributeAnyOverload4() throws Exception { guard.setConfigAdmin(ca); Subject subject = loginWithTestRoles("viewer"); - Subject.doAs(subject, (PrivilegedAction) () -> { + Subject.callAs(subject, (Callable) () -> { try { assertFalse(guard.canInvoke(mbs, on, "isFoo")); @@ -1132,7 +1132,7 @@ public void testCanSetAttributeAnyOverload() throws Exception { guard.setConfigAdmin(ca); Subject subject = loginWithTestRoles("viewer"); - Subject.doAs(subject, (PrivilegedAction) () -> { + Subject.callAs(subject, (Callable) () -> { try { assertTrue(guard.canInvoke(mbs, on, "setFoo")); @@ -1166,7 +1166,7 @@ public void testCanSetAttributeAnyOverload2() throws Exception { guard.setConfigAdmin(ca); Subject subject = loginWithTestRoles("viewer"); - Subject.doAs(subject, (PrivilegedAction) () -> { + Subject.callAs(subject, (Callable) () -> { try { assertFalse(guard.canInvoke(mbs, on, "setFoo")); @@ -1202,7 +1202,7 @@ public void testCanInvokeMBeanGetter() throws Exception { Subject subject = loginWithTestRoles("viewer"); - Subject.doAs(subject, (PrivilegedAction) () -> { + Subject.callAs(subject, (Callable) () -> { try { assertTrue(guard.canInvoke(mbs, on)); @@ -1238,7 +1238,7 @@ public void testCanInvokeMBeanGetter2() throws Exception { Subject subject = loginWithTestRoles("viewer"); - Subject.doAs(subject, (PrivilegedAction) () -> { + Subject.callAs(subject, (Callable) () -> { try { assertFalse(guard.canInvoke(mbs, on)); @@ -1274,7 +1274,7 @@ public void testCanInvokeMBeanGetter3() throws Exception { Subject subject = loginWithTestRoles("viewer"); - Subject.doAs(subject, (PrivilegedAction) () -> { + Subject.callAs(subject, (Callable) () -> { try { assertTrue(guard.canInvoke(mbs, on)); @@ -1310,7 +1310,7 @@ public void testCanInvokeMBeanSetter() throws Exception { Subject subject = loginWithTestRoles("viewer"); - Subject.doAs(subject, (PrivilegedAction) () -> { + Subject.callAs(subject, (Callable) () -> { try { assertTrue(guard.canInvoke(mbs, on)); @@ -1346,7 +1346,7 @@ public void testCanInvokeMBeanSetter2() throws Exception { Subject subject = loginWithTestRoles("viewer"); - Subject.doAs(subject, (PrivilegedAction) () -> { + Subject.callAs(subject, (Callable) () -> { try { assertFalse(guard.canInvoke(mbs, on)); @@ -1374,7 +1374,7 @@ public void testCanInvokeMethod() throws Exception { Subject subject = loginWithTestRoles("viewer"); - Subject.doAs(subject, (PrivilegedAction) () -> { + Subject.callAs(subject, (Callable) () -> { try { assertTrue(guard.canInvoke(null, on, "dodo", new String[]{"java.lang.String"})); assertTrue(guard.canInvoke(null, on, "doit", new String[]{"java.lang.String", "java.lang.String"})); @@ -1407,7 +1407,7 @@ public void testCanInvokeMethod2() throws Exception { Subject subject = loginWithTestRoles("viewer"); - Subject.doAs(subject, (PrivilegedAction) () -> { + Subject.callAs(subject, (Callable) () -> { try { assertTrue(guard.canInvoke(null, on, "doit", new String[]{"java.lang.String"})); assertTrue(guard.canInvoke(null, on, "doit", new String[]{})); diff --git a/pom.xml b/pom.xml index 56e3369e4e6..afcf0fefa98 100644 --- a/pom.xml +++ b/pom.xml @@ -150,7 +150,8 @@ 1695310533 - 11 + 21 + 21 scm:git:https://gitbox.apache.org/repos/asf/karaf.git scm:git:https://gitbox.apache.org/repos/asf/karaf.git @@ -449,6 +450,15 @@ + + org.apache.maven.plugins + maven-compiler-plugin + + + -Xlint:deprecation + + + org.apache.maven.plugins maven-eclipse-plugin @@ -632,7 +642,8 @@ [3.8.8,4) - [17,) + + [21,) @@ -898,7 +909,7 @@ org.apache.maven.plugins maven-javadoc-plugin - 1.8 + 21 diff --git a/service/guard/src/test/java/org/apache/karaf/service/guard/impl/GuardProxyCatalogTest.java b/service/guard/src/test/java/org/apache/karaf/service/guard/impl/GuardProxyCatalogTest.java index 21bb8f993f1..54bb4b737d3 100644 --- a/service/guard/src/test/java/org/apache/karaf/service/guard/impl/GuardProxyCatalogTest.java +++ b/service/guard/src/test/java/org/apache/karaf/service/guard/impl/GuardProxyCatalogTest.java @@ -28,9 +28,9 @@ import java.io.IOException; import java.security.Principal; -import java.security.PrivilegedAction; import java.util.ArrayList; import java.util.Arrays; +import java.util.concurrent.Callable; import java.util.Collection; import java.util.Collections; import java.util.Dictionary; @@ -338,7 +338,7 @@ public void testInvocationBlocking1() throws Exception { // Run with the right credentials so we can test the expected roles Subject subject = new Subject(); subject.getPrincipals().add(new RolePrincipal("b")); - Subject.doAs(subject, (PrivilegedAction) () -> { + Subject.callAs(subject, (Callable) () -> { assertEquals("Doing it", ((TestServiceAPI) proxy).doit()); if (!runningUnderCoverage) { try { @@ -369,7 +369,7 @@ public void testInvocationBlocking2() throws Exception { // Run with the right credentials so we can test the expected roles Subject subject = new Subject(); subject.getPrincipals().add(new RolePrincipal("b")); - Subject.doAs(subject, (PrivilegedAction) () -> { + Subject.callAs(subject, (Callable) () -> { if (!runningUnderCoverage) { assertEquals(-42L, ((TestObjectWithoutInterface) proxy).compute(42L)); try { @@ -414,7 +414,7 @@ public String doit() { // Run with the right credentials so we can test the expected roles Subject subject = new Subject(); subject.getPrincipals().add(new RolePrincipal("c")); - Subject.doAs(subject, (PrivilegedAction) () -> { + Subject.callAs(subject, (Callable) () -> { assertEquals("Doing it", ((TestServiceAPI) proxy).doit()); return null; }); @@ -422,7 +422,7 @@ public String doit() { Subject subject2 = new Subject(); subject2.getPrincipals().add(new RolePrincipal("b")); subject2.getPrincipals().add(new RolePrincipal("f")); - Subject.doAs(subject2, (PrivilegedAction) () -> { + Subject.callAs(subject2, (Callable) () -> { try { assertEquals("Doing it", ((TestServiceAPI) proxy).doit()); fail("Should have been blocked"); @@ -450,7 +450,7 @@ public void testInvocationBlocking4() throws Exception { // Run with the right credentials so we can test the expected roles Subject subject = new Subject(); subject.getPrincipals().add(new RolePrincipal("b")); - Subject.doAs(subject, (PrivilegedAction) () -> { + Subject.callAs(subject, (Callable) () -> { assertEquals("Doing it", ((TestServiceAPI) proxy).doit()); if (!runningUnderCoverage) { assertEquals(42L, ((TestObjectWithoutInterface) proxy).compute(-42L)); @@ -478,7 +478,7 @@ public void testInvocationBlocking5() throws Exception { // Invoke the service with role 'c'. Subject subject = new Subject(); subject.getPrincipals().add(new RolePrincipal("c")); - Subject.doAs(subject, (PrivilegedAction) () -> { + Subject.callAs(subject, (Callable) () -> { assertEquals("The invocation under role 'c' should be ok, as there are no rules specified " + "for this service at all.", "HELLO", ((TestServiceAPI2) proxy).doit("hello")); return null; @@ -507,7 +507,7 @@ public void testInvocationBlocking6() throws Exception { subject.getPrincipals().add(new RolePrincipal("a")); subject.getPrincipals().add(new RolePrincipal("b")); subject.getPrincipals().add(new RolePrincipal("c")); - Subject.doAs(subject, (PrivilegedAction) () -> { + Subject.callAs(subject, (Callable) () -> { try { ((TestServiceAPI2) proxy).doit("hello"); fail("The invocation should not process as the 'doit' operation has no roles associated with it"); @@ -533,7 +533,7 @@ public void testInvocationBlocking7() throws Exception { final Object proxy = testCreateProxy(bc, new Class [] {TestServiceAPI3.class}, new TestService3()); Subject s1 = new Subject(); - Subject.doAs(s1, (PrivilegedAction) () -> { + Subject.callAs(s1, (Callable) () -> { TestServiceAPI3 obj = (TestServiceAPI3) proxy; assertEquals("Should have allowed this invocation for any (or no) role", -7, obj.foo(7)); try { @@ -556,7 +556,7 @@ public void testInvocationBlocking7() throws Exception { s2.getPrincipals().add(new RolePrincipal("a")); s2.getPrincipals().add(new RolePrincipal("b")); s2.getPrincipals().add(new RolePrincipal("d")); - Subject.doAs(s2, (PrivilegedAction) () -> { + Subject.callAs(s2, (Callable) () -> { TestServiceAPI3 obj = (TestServiceAPI3) proxy; assertEquals(42, obj.foo()); assertEquals(99, obj.bar()); @@ -585,7 +585,7 @@ public String getName() { Subject s1 = new Subject(); s1.getPrincipals().add(new RolePrincipal("role1")); - Subject.doAs(s1, (PrivilegedAction) () -> { + Subject.callAs(s1, (Callable) () -> { try { ((TestServiceAPI) proxy).doit(); fail("Should have prevented this invocation as the custom role is required"); @@ -598,7 +598,7 @@ public String getName() { Subject s2 = new Subject(); s2.getPrincipals().add(new MyRolePrincipal()); - Subject.doAs(s2, (PrivilegedAction) () -> { + Subject.callAs(s2, (Callable) () -> { ((TestServiceAPI) proxy).doit(); // Should work, the custom role is there return null; }); @@ -606,7 +606,7 @@ public String getName() { Subject s3 = new Subject(); s3.getPrincipals().add(new MyRolePrincipal()); s3.getPrincipals().add(new RolePrincipal("role1")); - Subject.doAs(s3, (PrivilegedAction) () -> { + Subject.callAs(s3, (Callable) () -> { ((TestServiceAPI) proxy).doit(); // Should work, the custom role is there return null; }); diff --git a/services/eventadmin/src/main/java/org/apache/felix/eventadmin/impl/handler/EventAdminImpl.java b/services/eventadmin/src/main/java/org/apache/felix/eventadmin/impl/handler/EventAdminImpl.java index 5491865dd9a..04188de856b 100644 --- a/services/eventadmin/src/main/java/org/apache/felix/eventadmin/impl/handler/EventAdminImpl.java +++ b/services/eventadmin/src/main/java/org/apache/felix/eventadmin/impl/handler/EventAdminImpl.java @@ -143,7 +143,7 @@ private Event prepareEvent(Event event) { boolean needSubject = addSubject && !event.containsProperty(SUBJECT); Subject subject = null; if (needSubject) { - subject = Subject.getSubject(AccessController.getContext()); + subject = Subject.current(); needSubject = (subject != null); } if (needTimeStamp || needSubject) { diff --git a/shell/console/src/main/java/org/apache/karaf/shell/security/impl/SecuredCommandProcessorImpl.java b/shell/console/src/main/java/org/apache/karaf/shell/security/impl/SecuredCommandProcessorImpl.java index 8ae524c936d..6b882ec9002 100644 --- a/shell/console/src/main/java/org/apache/karaf/shell/security/impl/SecuredCommandProcessorImpl.java +++ b/shell/console/src/main/java/org/apache/karaf/shell/security/impl/SecuredCommandProcessorImpl.java @@ -58,8 +58,7 @@ private SecuredCommandProcessorImpl(BundleContext bc, ServiceReference bundleContext = bc; threadIOServiceReference = sr; - AccessControlContext acc = AccessController.getContext(); - Subject sub = Subject.getSubject(acc); + Subject sub = Subject.current(); if (sub == null) throw new SecurityException("No current Subject in the Access Control Context"); diff --git a/shell/console/src/main/java/org/apache/karaf/shell/util/ShellUtil.java b/shell/console/src/main/java/org/apache/karaf/shell/util/ShellUtil.java index 5942a890df8..4d75d3fa4a6 100644 --- a/shell/console/src/main/java/org/apache/karaf/shell/util/ShellUtil.java +++ b/shell/console/src/main/java/org/apache/karaf/shell/util/ShellUtil.java @@ -170,8 +170,7 @@ public static void logException(CommandSession session, Throwable t) { } public static String getCurrentUserName() { - AccessControlContext acc = AccessController.getContext(); - final Subject subject = Subject.getSubject(acc); + final Subject subject = Subject.current(); if (subject != null && subject.getPrincipals(UserPrincipal.class).iterator().hasNext()) { return subject.getPrincipals(UserPrincipal.class).iterator().next().getName(); } else { diff --git a/shell/core/src/main/java/org/apache/karaf/shell/impl/console/osgi/secured/SecuredSessionFactoryImpl.java b/shell/core/src/main/java/org/apache/karaf/shell/impl/console/osgi/secured/SecuredSessionFactoryImpl.java index e9544265ea6..77a8d8568d0 100644 --- a/shell/core/src/main/java/org/apache/karaf/shell/impl/console/osgi/secured/SecuredSessionFactoryImpl.java +++ b/shell/core/src/main/java/org/apache/karaf/shell/impl/console/osgi/secured/SecuredSessionFactoryImpl.java @@ -278,11 +278,7 @@ static boolean currentUserHasRole(String requestedRole) { role = requestedRole; } - AccessControlContext acc = AccessController.getContext(); - if (acc == null) { - return false; - } - Subject subject = Subject.getSubject(acc); + Subject subject = Subject.current(); if (subject == null) { return false; diff --git a/shell/core/src/main/java/org/apache/karaf/shell/support/ShellUtil.java b/shell/core/src/main/java/org/apache/karaf/shell/support/ShellUtil.java index 862a895c8e4..d2d6340f2ff 100644 --- a/shell/core/src/main/java/org/apache/karaf/shell/support/ShellUtil.java +++ b/shell/core/src/main/java/org/apache/karaf/shell/support/ShellUtil.java @@ -212,8 +212,7 @@ private static String getPrintStackTraces(Session session) { } public static String getCurrentUserName() { - AccessControlContext acc = AccessController.getContext(); - final Subject subject = Subject.getSubject(acc); + final Subject subject = Subject.current(); if (subject != null && subject.getPrincipals(UserPrincipal.class).iterator().hasNext()) { return subject.getPrincipals(UserPrincipal.class).iterator().next().getName(); } else { diff --git a/tooling/karaf-maven-plugin/pom.xml b/tooling/karaf-maven-plugin/pom.xml index 10b63835064..bc4f5827aee 100644 --- a/tooling/karaf-maven-plugin/pom.xml +++ b/tooling/karaf-maven-plugin/pom.xml @@ -376,8 +376,7 @@ org.apache.maven.plugins maven-compiler-plugin - 1.8 - 1.8 + 21 256M ${compiler.fork} diff --git a/tooling/karaf-maven-plugin/src/it/test-aggregate-features/pom.xml b/tooling/karaf-maven-plugin/src/it/test-aggregate-features/pom.xml index f0009ac396c..efc3d39e8fa 100644 --- a/tooling/karaf-maven-plugin/src/it/test-aggregate-features/pom.xml +++ b/tooling/karaf-maven-plugin/src/it/test-aggregate-features/pom.xml @@ -47,8 +47,6 @@ org.apache.maven.plugins maven-compiler-plugin - 1.8 - 1.8 256M ${compiler.fork} diff --git a/tooling/karaf-maven-plugin/src/it/test-basic-generation/pom.xml b/tooling/karaf-maven-plugin/src/it/test-basic-generation/pom.xml index 45122f8b064..54ca3b8a673 100644 --- a/tooling/karaf-maven-plugin/src/it/test-basic-generation/pom.xml +++ b/tooling/karaf-maven-plugin/src/it/test-basic-generation/pom.xml @@ -36,8 +36,6 @@ org.apache.maven.plugins maven-compiler-plugin - 1.8 - 1.8 256M ${compiler.fork} diff --git a/tooling/karaf-maven-plugin/src/it/test-check-dependencies-failure/pom.xml b/tooling/karaf-maven-plugin/src/it/test-check-dependencies-failure/pom.xml index f4b22b2f53f..29fc8781486 100644 --- a/tooling/karaf-maven-plugin/src/it/test-check-dependencies-failure/pom.xml +++ b/tooling/karaf-maven-plugin/src/it/test-check-dependencies-failure/pom.xml @@ -43,8 +43,6 @@ org.apache.maven.plugins maven-compiler-plugin - 1.8 - 1.8 256M ${compiler.fork} diff --git a/tooling/karaf-maven-plugin/src/it/test-check-dependencies/pom.xml b/tooling/karaf-maven-plugin/src/it/test-check-dependencies/pom.xml index fb2e03ac23e..a83ec2b9078 100644 --- a/tooling/karaf-maven-plugin/src/it/test-check-dependencies/pom.xml +++ b/tooling/karaf-maven-plugin/src/it/test-check-dependencies/pom.xml @@ -44,8 +44,6 @@ org.apache.maven.plugins maven-compiler-plugin - 1.8 - 1.8 256M ${compiler.fork} diff --git a/tooling/karaf-maven-plugin/src/it/test-feature-dependencies/pom.xml b/tooling/karaf-maven-plugin/src/it/test-feature-dependencies/pom.xml index b60f6502281..643ae0fddb3 100644 --- a/tooling/karaf-maven-plugin/src/it/test-feature-dependencies/pom.xml +++ b/tooling/karaf-maven-plugin/src/it/test-feature-dependencies/pom.xml @@ -47,8 +47,6 @@ org.apache.maven.plugins maven-compiler-plugin - 1.8 - 1.8 256M ${compiler.fork} diff --git a/tooling/karaf-maven-plugin/src/it/test-feature-use-version-range-transfer-properties/transitive/pom.xml b/tooling/karaf-maven-plugin/src/it/test-feature-use-version-range-transfer-properties/transitive/pom.xml index 42ec7de9b4a..538bbe6fe48 100644 --- a/tooling/karaf-maven-plugin/src/it/test-feature-use-version-range-transfer-properties/transitive/pom.xml +++ b/tooling/karaf-maven-plugin/src/it/test-feature-use-version-range-transfer-properties/transitive/pom.xml @@ -34,8 +34,6 @@ org.apache.maven.plugins maven-compiler-plugin - 1.8 - 1.8 256M ${compiler.fork} diff --git a/tooling/karaf-maven-plugin/src/it/test-include-project-artifact/pom.xml b/tooling/karaf-maven-plugin/src/it/test-include-project-artifact/pom.xml index 925f726230f..ef3459b0804 100644 --- a/tooling/karaf-maven-plugin/src/it/test-include-project-artifact/pom.xml +++ b/tooling/karaf-maven-plugin/src/it/test-include-project-artifact/pom.xml @@ -36,8 +36,6 @@ org.apache.maven.plugins maven-compiler-plugin - 1.8 - 1.8 256M ${compiler.fork} diff --git a/tooling/karaf-maven-plugin/src/it/test-input-file/pom.xml b/tooling/karaf-maven-plugin/src/it/test-input-file/pom.xml index a135fb1b30e..b3d5c9a0600 100644 --- a/tooling/karaf-maven-plugin/src/it/test-input-file/pom.xml +++ b/tooling/karaf-maven-plugin/src/it/test-input-file/pom.xml @@ -42,8 +42,6 @@ org.apache.maven.plugins maven-compiler-plugin - 1.8 - 1.8 256M ${compiler.fork} diff --git a/tooling/karaf-maven-plugin/src/it/test-recursive/pom.xml b/tooling/karaf-maven-plugin/src/it/test-recursive/pom.xml index 46e8ac969b4..d5d4d951bcc 100644 --- a/tooling/karaf-maven-plugin/src/it/test-recursive/pom.xml +++ b/tooling/karaf-maven-plugin/src/it/test-recursive/pom.xml @@ -43,8 +43,6 @@ org.apache.maven.plugins maven-compiler-plugin - 1.8 - 1.8 256M ${compiler.fork} diff --git a/tooling/karaf-maven-plugin/src/it/test-rename-main-feature/pom.xml b/tooling/karaf-maven-plugin/src/it/test-rename-main-feature/pom.xml index d81411df4ee..eb704fb2da2 100644 --- a/tooling/karaf-maven-plugin/src/it/test-rename-main-feature/pom.xml +++ b/tooling/karaf-maven-plugin/src/it/test-rename-main-feature/pom.xml @@ -36,8 +36,6 @@ org.apache.maven.plugins maven-compiler-plugin - 1.8 - 1.8 256M ${compiler.fork} diff --git a/tooling/karaf-maven-plugin/src/it/test-repository-dependencies/pom.xml b/tooling/karaf-maven-plugin/src/it/test-repository-dependencies/pom.xml index 063e4ff3750..9bf5dfbec4e 100644 --- a/tooling/karaf-maven-plugin/src/it/test-repository-dependencies/pom.xml +++ b/tooling/karaf-maven-plugin/src/it/test-repository-dependencies/pom.xml @@ -45,8 +45,6 @@ org.apache.maven.plugins maven-compiler-plugin - 1.8 - 1.8 256M ${compiler.fork} diff --git a/tooling/karaf-maven-plugin/src/it/test-run-bundle/pom.xml b/tooling/karaf-maven-plugin/src/it/test-run-bundle/pom.xml index ec2d2342cf3..eb20c8100d8 100644 --- a/tooling/karaf-maven-plugin/src/it/test-run-bundle/pom.xml +++ b/tooling/karaf-maven-plugin/src/it/test-run-bundle/pom.xml @@ -32,8 +32,6 @@ org.apache.maven.plugins maven-compiler-plugin - 1.8 - 1.8 256M ${compiler.fork} diff --git a/tooling/karaf-maven-plugin/src/it/test-simplify-bundles/pom.xml b/tooling/karaf-maven-plugin/src/it/test-simplify-bundles/pom.xml index 6eebb6565e8..b0b8dd7aa8e 100644 --- a/tooling/karaf-maven-plugin/src/it/test-simplify-bundles/pom.xml +++ b/tooling/karaf-maven-plugin/src/it/test-simplify-bundles/pom.xml @@ -56,8 +56,6 @@ org.apache.maven.plugins maven-compiler-plugin - 1.8 - 1.8 256M ${compiler.fork} diff --git a/tooling/karaf-maven-plugin/src/it/test-transitive-as-dependency/pom.xml b/tooling/karaf-maven-plugin/src/it/test-transitive-as-dependency/pom.xml index 3dde7c68be5..1c7d73eb019 100644 --- a/tooling/karaf-maven-plugin/src/it/test-transitive-as-dependency/pom.xml +++ b/tooling/karaf-maven-plugin/src/it/test-transitive-as-dependency/pom.xml @@ -45,8 +45,6 @@ org.apache.maven.plugins maven-compiler-plugin - 1.8 - 1.8 256M ${compiler.fork} diff --git a/tooling/karaf-maven-plugin/src/it/test-type-classifier/pom.xml b/tooling/karaf-maven-plugin/src/it/test-type-classifier/pom.xml index 3fc5a796d12..57b5fe95565 100644 --- a/tooling/karaf-maven-plugin/src/it/test-type-classifier/pom.xml +++ b/tooling/karaf-maven-plugin/src/it/test-type-classifier/pom.xml @@ -37,8 +37,6 @@ org.apache.maven.plugins maven-compiler-plugin - 1.8 - 1.8 256M ${compiler.fork} diff --git a/util/src/main/java/org/apache/karaf/util/ThreadUtils.java b/util/src/main/java/org/apache/karaf/util/ThreadUtils.java index 9ea69e3ac0e..ad2a764972f 100644 --- a/util/src/main/java/org/apache/karaf/util/ThreadUtils.java +++ b/util/src/main/java/org/apache/karaf/util/ThreadUtils.java @@ -38,8 +38,7 @@ private static class NamedThreadFactory implements ThreadFactory { private final String namePrefix; public NamedThreadFactory(String prefix) { - SecurityManager s = System.getSecurityManager(); - group = (s != null) ? s.getThreadGroup() : Thread.currentThread().getThreadGroup(); + group = Thread.currentThread().getThreadGroup(); namePrefix = prefix + "-" + poolNumber.getAndIncrement() + "-thread-"; } diff --git a/util/src/main/java/org/apache/karaf/util/jaas/JaasHelper.java b/util/src/main/java/org/apache/karaf/util/jaas/JaasHelper.java index e9df8242daf..d121731081f 100644 --- a/util/src/main/java/org/apache/karaf/util/jaas/JaasHelper.java +++ b/util/src/main/java/org/apache/karaf/util/jaas/JaasHelper.java @@ -38,11 +38,7 @@ public static boolean currentUserHasRole(String requestedRole) { return true; } - AccessControlContext acc = AccessController.getContext(); - if (acc == null) { - return false; - } - Subject subject = Subject.getSubject(acc); + Subject subject = Subject.current(); if (subject == null) { return false; } diff --git a/util/src/main/java/org/apache/karaf/util/tracker/BaseActivator.java b/util/src/main/java/org/apache/karaf/util/tracker/BaseActivator.java index de39cb0844c..7864ff60566 100644 --- a/util/src/main/java/org/apache/karaf/util/tracker/BaseActivator.java +++ b/util/src/main/java/org/apache/karaf/util/tracker/BaseActivator.java @@ -66,8 +66,7 @@ public class BaseActivator implements BundleActivator, Runnable, ThreadFactory { private final String namePrefix; public BaseActivator() { - SecurityManager s = System.getSecurityManager(); - group = (s != null) ? s.getThreadGroup() : Thread.currentThread().getThreadGroup(); + group = Thread.currentThread().getThreadGroup(); namePrefix = "activator-" + poolNumber.getAndIncrement() + "-thread-"; } diff --git a/webconsole/gogo/src/main/java/org/apache/karaf/webconsole/gogo/GogoPlugin.java b/webconsole/gogo/src/main/java/org/apache/karaf/webconsole/gogo/GogoPlugin.java index 9c7b5dc182f..3529ceb2e5d 100644 --- a/webconsole/gogo/src/main/java/org/apache/karaf/webconsole/gogo/GogoPlugin.java +++ b/webconsole/gogo/src/main/java/org/apache/karaf/webconsole/gogo/GogoPlugin.java @@ -193,8 +193,7 @@ public SessionTerminal() throws IOException { } private String getCurrentUserName() { - AccessControlContext acc = AccessController.getContext(); - final Subject subject = Subject.getSubject(acc); + final Subject subject = Subject.current(); if (subject != null && subject.getPrincipals().iterator().hasNext()) { return subject.getPrincipals(UserPrincipal.class).iterator().next().getName(); } else { From f02d8f338a64b70b9b09edaea45d61c8ac9561ad Mon Sep 17 00:00:00 2001 From: Holger Friedrich Date: Wed, 15 Apr 2026 01:23:19 +0200 Subject: [PATCH 2/5] disable org.osgi.framework.security in JavaSecurityTest --- .../test/java/org/apache/karaf/itests/JavaSecurityTest.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/itests/test/src/test/java/org/apache/karaf/itests/JavaSecurityTest.java b/itests/test/src/test/java/org/apache/karaf/itests/JavaSecurityTest.java index 2d6459b0a6b..d2cfa7a59e1 100644 --- a/itests/test/src/test/java/org/apache/karaf/itests/JavaSecurityTest.java +++ b/itests/test/src/test/java/org/apache/karaf/itests/JavaSecurityTest.java @@ -62,7 +62,8 @@ public Option[] config() { // Add some extra options used by this test... options.addAll(Arrays.asList( editConfigurationFilePut("etc/system.properties", "java.security.policy", "${karaf.etc}/all.policy"), - editConfigurationFilePut("etc/system.properties", "org.osgi.framework.security", "osgi"), + // This is no longer allowed as felix framework 7.0.5 calls System.getSecurityManager() in case it is there, see Felix.java + // editConfigurationFilePut("etc/system.properties", "org.osgi.framework.security", "osgi"), editConfigurationFilePut("etc/system.properties", "org.osgi.framework.trust.repositories", "${karaf.etc}/trustStore.ks"), editConfigurationFilePut("etc/startup.properties", "mvn:org.apache.felix/org.apache.felix.framework.security/" + version, "1"), replaceConfigurationFile("system/org/apache/felix/org.apache.felix.framework.security/" + version + "/org.apache.felix.framework.security-" + version + ".jar", temp.toFile()))); From 4a8d769f3dbef05a6910b403a99167c28e50414b Mon Sep 17 00:00:00 2001 From: Fryderyk Wysocki Date: Mon, 8 Jun 2026 23:58:53 +0200 Subject: [PATCH 3/5] Updated how Java 21 is set in various places --- BUILDING.md | 4 +- .../resources/archetype-resources/pom.xml | 2 +- assemblies/apache-karaf-minimal/pom.xml | 2 +- assemblies/apache-karaf-mix/pom.xml | 2 +- assemblies/apache-karaf/pom.xml | 2 +- assemblies/features/enterprise/pom.xml | 2 +- assemblies/features/integration/pom.xml | 2 +- assemblies/features/specs/pom.xml | 2 +- assemblies/features/spring/pom.xml | 2 +- assemblies/features/standard/pom.xml | 4 +- .../karaf-docker-example-dynamic-dist/pom.xml | 2 +- .../karaf-docker-example-static-dist/pom.xml | 2 +- .../core/internal/InstanceServiceImpl.java | 49 ++++++------ .../java/org/apache/karaf/itests/JtaTest.java | 76 +++++-------------- .../features/EnterpriseFeaturesTest.java | 1 - .../apache/karaf/itests/util/RunIfRules.java | 40 ---------- pom.xml | 9 ++- 17 files changed, 58 insertions(+), 145 deletions(-) delete mode 100644 itests/test/src/test/java/org/apache/karaf/itests/util/RunIfRules.java diff --git a/BUILDING.md b/BUILDING.md index 4286805b25a..408efd5fe9b 100644 --- a/BUILDING.md +++ b/BUILDING.md @@ -21,13 +21,13 @@ ## Initial Setup -1. Install J2SE 11 SDK (or later) +1. Install J2SE 21 SDK (or later) 2. Make sure that your JAVA_HOME environment variable is set to the newly installed JDK location, and that your PATH includes `%JAVA_HOME%\bin` (windows) or `$JAVA_HOME$/bin` (unix). -3. Install Maven 3.8.0 (or later), which can be downloaded from +3. Install Maven 3.8.8 (or later), which can be downloaded from http://maven.apache.org/download.html. Make sure that your PATH includes the `$MVN_HOME/bin` directory. diff --git a/archetypes/assembly/src/main/resources/archetype-resources/pom.xml b/archetypes/assembly/src/main/resources/archetype-resources/pom.xml index d8f83f8bffb..c0fff59c068 100644 --- a/archetypes/assembly/src/main/resources/archetype-resources/pom.xml +++ b/archetypes/assembly/src/main/resources/archetype-resources/pom.xml @@ -174,7 +174,7 @@ - 21 + ^javaVersion^ diff --git a/assemblies/apache-karaf-minimal/pom.xml b/assemblies/apache-karaf-minimal/pom.xml index 481bbedd666..dff15d80164 100644 --- a/assemblies/apache-karaf-minimal/pom.xml +++ b/assemblies/apache-karaf-minimal/pom.xml @@ -145,7 +145,7 @@ !org.apache.karaf.command.acl.*, * - 21 + ${javaVersion} diff --git a/assemblies/apache-karaf-mix/pom.xml b/assemblies/apache-karaf-mix/pom.xml index 0dad89e8c71..4c4039b623c 100644 --- a/assemblies/apache-karaf-mix/pom.xml +++ b/assemblies/apache-karaf-mix/pom.xml @@ -187,7 +187,7 @@ - 21 + ${javaVersion} ${project.build.directory} Apache Karaf Mix diff --git a/assemblies/apache-karaf/pom.xml b/assemblies/apache-karaf/pom.xml index 60dd7a90911..2a263eca686 100644 --- a/assemblies/apache-karaf/pom.xml +++ b/assemblies/apache-karaf/pom.xml @@ -178,7 +178,7 @@ - 21 + ${javaVersion} ${project.build.directory} Apache Karaf (full) diff --git a/assemblies/features/enterprise/pom.xml b/assemblies/features/enterprise/pom.xml index 281a0c4d0ee..d8cc722ba0d 100644 --- a/assemblies/features/enterprise/pom.xml +++ b/assemblies/features/enterprise/pom.xml @@ -214,7 +214,7 @@ file:${project.build.directory}/feature/feature.xml org.apache.karaf.features:framework - 21 + ${javaVersion} framework diff --git a/assemblies/features/integration/pom.xml b/assemblies/features/integration/pom.xml index a4ec1f608c5..0e4d7c326a5 100644 --- a/assemblies/features/integration/pom.xml +++ b/assemblies/features/integration/pom.xml @@ -105,7 +105,7 @@ file:${project.build.directory}/feature/feature.xml org.apache.karaf.features:framework - 21 + ${javaVersion} framework diff --git a/assemblies/features/specs/pom.xml b/assemblies/features/specs/pom.xml index 36ba1df5130..1558c26aeec 100644 --- a/assemblies/features/specs/pom.xml +++ b/assemblies/features/specs/pom.xml @@ -96,7 +96,7 @@ file:${project.build.directory}/feature/feature.xml org.apache.karaf.features:framework - 21 + ${javaVersion} framework diff --git a/assemblies/features/spring/pom.xml b/assemblies/features/spring/pom.xml index c04a2ca250c..8658b716938 100644 --- a/assemblies/features/spring/pom.xml +++ b/assemblies/features/spring/pom.xml @@ -158,7 +158,7 @@ file:${project.build.directory}/feature/feature.xml org.apache.karaf.features:framework - 21 + ${javaVersion} framework diff --git a/assemblies/features/standard/pom.xml b/assemblies/features/standard/pom.xml index c04f77a77b3..ed6a8b92ac2 100644 --- a/assemblies/features/standard/pom.xml +++ b/assemblies/features/standard/pom.xml @@ -476,7 +476,7 @@ file:${project.build.directory}/feature/feature.xml org.apache.karaf.features:framework - 21 + ${javaVersion} framework @@ -503,7 +503,7 @@ target/feature/feature.xml - features + features xml diff --git a/examples/karaf-docker-example/karaf-docker-example-dynamic-dist/pom.xml b/examples/karaf-docker-example/karaf-docker-example-dynamic-dist/pom.xml index 729a495cc3e..ad74a79ddac 100644 --- a/examples/karaf-docker-example/karaf-docker-example-dynamic-dist/pom.xml +++ b/examples/karaf-docker-example/karaf-docker-example-dynamic-dist/pom.xml @@ -138,7 +138,7 @@ - 21 + ${javaVersion} diff --git a/examples/karaf-docker-example/karaf-docker-example-static-dist/pom.xml b/examples/karaf-docker-example/karaf-docker-example-static-dist/pom.xml index dbc715cc36d..c43b7410187 100644 --- a/examples/karaf-docker-example/karaf-docker-example-static-dist/pom.xml +++ b/examples/karaf-docker-example/karaf-docker-example-static-dist/pom.xml @@ -108,7 +108,7 @@ static true static - 21 + ${javaVersion} diff --git a/instance/src/main/java/org/apache/karaf/instance/core/internal/InstanceServiceImpl.java b/instance/src/main/java/org/apache/karaf/instance/core/internal/InstanceServiceImpl.java index f208e8e59a4..71b285f3ee5 100644 --- a/instance/src/main/java/org/apache/karaf/instance/core/internal/InstanceServiceImpl.java +++ b/instance/src/main/java/org/apache/karaf/instance/core/internal/InstanceServiceImpl.java @@ -509,34 +509,29 @@ private static void doStart(InstanceState instance, String name, String javaOpts classpath.append(childClasspath); } - String jdkOpts; - if (!System.getProperty("java.version").startsWith("1.")) { - StringBuilder jdk9Classpath = classpathFromLibDir(new File(new File(System.getProperty("karaf.home"), "lib"), "jdk9plus")); - if (jdk9Classpath.length() > 0) { - classpath.append(System.getProperty("path.separator")); - classpath.append(jdk9Classpath); - } - jdkOpts = " --add-opens java.base/java.security=ALL-UNNAMED" + - " --add-opens java.base/java.net=ALL-UNNAMED" + - " --add-opens java.base/java.lang=ALL-UNNAMED" + - " --add-opens java.base/java.util=ALL-UNNAMED" + - " --add-opens java.naming/javax.naming.spi=ALL-UNNAMED" + - " --add-opens java.rmi/sun.rmi.transport.tcp=ALL-UNNAMED" + - " --add-exports=java.base/sun.net.www.protocol.file=ALL-UNNAMED" + - " --add-exports=java.base/sun.net.www.protocol.ftp=ALL-UNNAMED" + - " --add-exports=java.base/sun.net.www.protocol.http=ALL-UNNAMED" + - " --add-exports=java.base/sun.net.www.protocol.https=ALL-UNNAMED" + - " --add-exports=java.base/sun.net.www.protocol.jar=ALL-UNNAMED" + - " --add-exports=java.base/sun.net.www.content.text=ALL-UNNAMED" + - " --add-exports=jdk.xml.dom/org.w3c.dom.html=ALL-UNNAMED" + - " --add-exports=java.rmi/sun.rmi.registry=ALL-UNNAMED" + - " --add-exports=jdk.naming.rmi/com.sun.jndi.url.rmi=ALL-UNNAMED" + - " --add-exports=java.security.sasl/com.sun.security.sasl=ALL-UNNAMED" + - " --add-exports=java.naming/com.sun.jndi.ldap=ALL-UNNAMED"; - } else { - jdkOpts = " -Djava.endorsed.dirs=\"" + new File(new File(new File(System.getProperty("java.home"), "jre"), "lib"), "endorsed") + System.getProperty("path.separator") + new File(new File(System.getProperty("java.home"), "lib"), "endorsed") + "\"" - + " -Djava.ext.dirs=\"" + new File(new File(new File(System.getProperty("java.home"), "jre"), "lib"), "ext") + System.getProperty("path.separator") + new File(new File(System.getProperty("java.home"), "lib"), "ext") + System.getProperty("path.separator") + new File(libDir, "ext").getCanonicalPath() + "\""; + StringBuilder jdk9Classpath = classpathFromLibDir(new File(new File(System.getProperty("karaf.home"), "lib"), "jdk9plus")); + if (!jdk9Classpath.isEmpty()) { + classpath.append(File.pathSeparator); + classpath.append(jdk9Classpath); } + String jdkOpts = " --add-opens java.base/java.security=ALL-UNNAMED" + + " --add-opens java.base/java.net=ALL-UNNAMED" + + " --add-opens java.base/java.lang=ALL-UNNAMED" + + " --add-opens java.base/java.util=ALL-UNNAMED" + + " --add-opens java.naming/javax.naming.spi=ALL-UNNAMED" + + " --add-opens java.rmi/sun.rmi.transport.tcp=ALL-UNNAMED" + + " --add-exports=java.base/sun.net.www.protocol.file=ALL-UNNAMED" + + " --add-exports=java.base/sun.net.www.protocol.ftp=ALL-UNNAMED" + + " --add-exports=java.base/sun.net.www.protocol.http=ALL-UNNAMED" + + " --add-exports=java.base/sun.net.www.protocol.https=ALL-UNNAMED" + + " --add-exports=java.base/sun.net.www.protocol.jar=ALL-UNNAMED" + + " --add-exports=java.base/sun.net.www.content.text=ALL-UNNAMED" + + " --add-exports=jdk.xml.dom/org.w3c.dom.html=ALL-UNNAMED" + + " --add-exports=java.rmi/sun.rmi.registry=ALL-UNNAMED" + + " --add-exports=jdk.naming.rmi/com.sun.jndi.url.rmi=ALL-UNNAMED" + + " --add-exports=java.security.sasl/com.sun.security.sasl=ALL-UNNAMED" + + " --add-exports=java.naming/com.sun.jndi.ldap=ALL-UNNAMED"; + String command = "\"" + new File(System.getProperty("java.home"), ScriptUtils.isWindows() ? "bin\\java.exe" : "bin/java").getCanonicalPath() + "\" " + opts diff --git a/itests/test/src/test/java/org/apache/karaf/itests/JtaTest.java b/itests/test/src/test/java/org/apache/karaf/itests/JtaTest.java index 7a8dbc80490..04f7d3a5232 100644 --- a/itests/test/src/test/java/org/apache/karaf/itests/JtaTest.java +++ b/itests/test/src/test/java/org/apache/karaf/itests/JtaTest.java @@ -69,25 +69,17 @@ public Option[] config() { public void noSpecialFeatures() throws Exception { ClassLoader cl = FrameworkUtil.getBundle(this.getClass()).adapt(BundleWiring.class).getClassLoader(); - if (isJDK8OrEarlier()) { - // these classes should be boot delegated because they should be part of JDK8, all used ONLY - // in com.sun.corba.se.impl.javax.rmi.CORBA.Util.mapSystemException() - ensureLoadedFromSystem(cl, "jakarta.transaction.InvalidTransactionException"); - ensureLoadedFromSystem(cl, "jakarta.transaction.TransactionRequiredException"); - ensureLoadedFromSystem(cl, "jakarta.transaction.TransactionRolledbackException"); - } else { - // JDK9+ doesn't provide jakarta.transaction package at all - ensureNotFound(cl, "jakarta.transaction.InvalidTransactionException"); - ensureNotFound(cl, "jakarta.transaction.TransactionRequiredException"); - ensureNotFound(cl, "jakarta.transaction.TransactionRolledbackException"); - } + // JDK9+ doesn't provide jakarta.transaction package at all + ensureNotFound(cl, "jakarta.transaction.InvalidTransactionException"); + ensureNotFound(cl, "jakarta.transaction.TransactionRequiredException"); + ensureNotFound(cl, "jakarta.transaction.TransactionRolledbackException"); - // whatever the JDK, these classes should be available + // these classes should be available ensureLoadedFromSystem(cl, "javax.transaction.xa.XAException"); ensureLoadedFromSystem(cl, "javax.transaction.xa.XAResource"); ensureLoadedFromSystem(cl, "javax.transaction.xa.Xid"); - // whatever the JDK, these classes should NOT be available + // these classes should NOT be available ensureNotFound(cl, "jakarta.transaction.UserTransaction"); ensureNotFound(cl, "jakarta.transaction.TransactionManager"); } @@ -101,19 +93,12 @@ public void jakartaTransaction2_0() throws Exception { ClassLoader myCl = FrameworkUtil.getBundle(this.getClass()).adapt(BundleWiring.class).getClassLoader(); ClassLoader jtaCl = FrameworkUtil.getBundle(myCl.loadClass("jakarta.transaction.UserTransaction")).adapt(BundleWiring.class).getClassLoader(); - if (isJDK8OrEarlier()) { - // these classes should be boot delegated - ensureLoadedFromSystem(myCl, "jakarta.transaction.InvalidTransactionException"); - ensureLoadedFromSystem(myCl, "jakarta.transaction.TransactionRequiredException"); - ensureLoadedFromSystem(myCl, "jakarta.transaction.TransactionRolledbackException"); - } else { - // these classes ARE boot delegated, but can't be found in JDK, so they're loaded from the API bundle - ensureLoadedFromCl(myCl, jtaCl, "jakarta.transaction.InvalidTransactionException"); - ensureLoadedFromCl(myCl, jtaCl, "jakarta.transaction.TransactionRequiredException"); - ensureLoadedFromCl(myCl, jtaCl, "jakarta.transaction.TransactionRolledbackException"); - } + // these classes are boot delegated, but can't be found in JDK, so they're loaded from the API bundle + ensureLoadedFromCl(myCl, jtaCl, "jakarta.transaction.InvalidTransactionException"); + ensureLoadedFromCl(myCl, jtaCl, "jakarta.transaction.TransactionRequiredException"); + ensureLoadedFromCl(myCl, jtaCl, "jakarta.transaction.TransactionRolledbackException"); - // whatever the JDK, these classes should be available from system CL, even if jakarta.transaction-api/2.0.1 + // these classes should be available from system CL, even if jakarta.transaction-api/2.0.1 // exports javax.transaction.xa package ensureLoadedFromSystem(myCl, "javax.transaction.xa.XAException"); ensureLoadedFromSystem(myCl, "javax.transaction.xa.XAResource"); @@ -151,15 +136,9 @@ public void jakartaTransaction2_0AndDBCP2() throws Exception { ClassLoader myCl = FrameworkUtil.getBundle(this.getClass()).adapt(BundleWiring.class).getClassLoader(); ClassLoader jtaCl = FrameworkUtil.getBundle(myCl.loadClass("jakarta.transaction.UserTransaction")).adapt(BundleWiring.class).getClassLoader(); - if (isJDK8OrEarlier()) { - ensureLoadedFromSystem(myCl, "jakarta.transaction.InvalidTransactionException"); - ensureLoadedFromSystem(myCl, "jakarta.transaction.TransactionRequiredException"); - ensureLoadedFromSystem(myCl, "jakarta.transaction.TransactionRolledbackException"); - } else { - ensureLoadedFromCl(myCl, jtaCl, "jakarta.transaction.InvalidTransactionException"); - ensureLoadedFromCl(myCl, jtaCl, "jakarta.transaction.TransactionRequiredException"); - ensureLoadedFromCl(myCl, jtaCl, "jakarta.transaction.TransactionRolledbackException"); - } + ensureLoadedFromCl(myCl, jtaCl, "jakarta.transaction.InvalidTransactionException"); + ensureLoadedFromCl(myCl, jtaCl, "jakarta.transaction.TransactionRequiredException"); + ensureLoadedFromCl(myCl, jtaCl, "jakarta.transaction.TransactionRolledbackException"); ensureLoadedFromSystem(myCl, "javax.transaction.xa.Xid"); ensureLoadedFromSystem(jtaCl, "javax.transaction.xa.Xid"); @@ -190,15 +169,9 @@ public void jakartaTransaction2_0_1AndDBCP2() throws Exception { ClassLoader myCl = FrameworkUtil.getBundle(this.getClass()).adapt(BundleWiring.class).getClassLoader(); ClassLoader jtaCl = FrameworkUtil.getBundle(myCl.loadClass("jakarta.transaction.UserTransaction")).adapt(BundleWiring.class).getClassLoader(); - if (isJDK8OrEarlier()) { - ensureLoadedFromSystem(myCl, "jakarta.transaction.InvalidTransactionException"); - ensureLoadedFromSystem(myCl, "jakarta.transaction.TransactionRequiredException"); - ensureLoadedFromSystem(myCl, "jakarta.transaction.TransactionRolledbackException"); - } else { - ensureLoadedFromCl(myCl, jtaCl, "jakarta.transaction.InvalidTransactionException"); - ensureLoadedFromCl(myCl, jtaCl, "jakarta.transaction.TransactionRequiredException"); - ensureLoadedFromCl(myCl, jtaCl, "jakarta.transaction.TransactionRolledbackException"); - } + ensureLoadedFromCl(myCl, jtaCl, "jakarta.transaction.InvalidTransactionException"); + ensureLoadedFromCl(myCl, jtaCl, "jakarta.transaction.TransactionRequiredException"); + ensureLoadedFromCl(myCl, jtaCl, "jakarta.transaction.TransactionRolledbackException"); ensureLoadedFromSystem(jtaCl, "javax.transaction.xa.Xid"); ensureLoadedFromSystem(myCl, "javax.transaction.xa.Xid"); @@ -235,19 +208,4 @@ private void ensureNotFound(ClassLoader cl, String className) { } } - private boolean isJDK8OrEarlier() { - String v = System.getProperty("java.specification.version"); - try { - if (v.contains(".")) { - float f = Float.parseFloat(v); - return f < 1.9F; - } else { - int i = Integer.parseInt(v); - return i < 9; - } - } catch (NumberFormatException ignored) { - return true; - } - } - } diff --git a/itests/test/src/test/java/org/apache/karaf/itests/features/EnterpriseFeaturesTest.java b/itests/test/src/test/java/org/apache/karaf/itests/features/EnterpriseFeaturesTest.java index 5e1253f8cda..852a11cbac4 100644 --- a/itests/test/src/test/java/org/apache/karaf/itests/features/EnterpriseFeaturesTest.java +++ b/itests/test/src/test/java/org/apache/karaf/itests/features/EnterpriseFeaturesTest.java @@ -14,7 +14,6 @@ package org.apache.karaf.itests.features; import org.apache.karaf.itests.BaseTest; -import org.apache.karaf.itests.util.RunIfRules.RunIfNotOnJdk8; import org.apache.karaf.itests.util.RunIfRule; import org.junit.Ignore; diff --git a/itests/test/src/test/java/org/apache/karaf/itests/util/RunIfRules.java b/itests/test/src/test/java/org/apache/karaf/itests/util/RunIfRules.java deleted file mode 100644 index 35c253b5134..00000000000 --- a/itests/test/src/test/java/org/apache/karaf/itests/util/RunIfRules.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Licensed 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.karaf.itests.util; - -import java.lang.annotation.Inherited; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; - -import org.apache.karaf.itests.util.RunIfRule.RunIf; -import org.apache.karaf.itests.util.RunIfRule.RunIfCondition; - -public class RunIfRules { - - @RunIf(condition = RunIfNotOnJdk8Condition.class) - @Retention(RetentionPolicy.RUNTIME) - @Inherited - public @interface RunIfNotOnJdk8 { - - } - - public static class RunIfNotOnJdk8Condition implements RunIfCondition { - @Override - public boolean isSatisfied() { - String jdk = System.getProperty("java.specification.version"); - return jdk.equals("1.5") || jdk.equals("1.6") || jdk.equals("1.7"); - } - } - -} diff --git a/pom.xml b/pom.xml index afcf0fefa98..27a0f0d915c 100644 --- a/pom.xml +++ b/pom.xml @@ -150,8 +150,9 @@ 1695310533 - 21 - 21 + 21 + ${javaVersion} + ${javaVersion} scm:git:https://gitbox.apache.org/repos/asf/karaf.git scm:git:https://gitbox.apache.org/repos/asf/karaf.git @@ -643,7 +644,7 @@ - [21,) + [${javaVersion},) @@ -909,7 +910,7 @@ org.apache.maven.plugins maven-javadoc-plugin - 21 + ${javaVersion} From 507d461fd2112e5c580fc28f097325e5a25c634e Mon Sep 17 00:00:00 2001 From: Holger Friedrich Date: Sun, 19 Jul 2026 13:04:51 +0200 Subject: [PATCH 4/5] Fix Subject propagation for shell RBAC on JDK 25 Subject.current()/callAs() use a plain ScopedValue on JDK 25 (no SecurityManager fallback like on JDK 21), which doesn't survive a new Thread or an ExecutorService hop. Since Felix Gogo runs each command on its own executor thread, this broke current-user lookup and RBAC checks (bundle:list/bundle:info losing bundle visibility). - JaasHelper.doAs/runAs now use Subject.callAs() instead of the old AccessControlContext/SubjectDomainCombiner plumbing; drop the now dead OsgiSubjectDomainCombiner/DelegatingProtectionDomain classes. - SecuredCommand.execute() re-binds the subject from the session on whatever thread runs the command, since Session is always passed explicitly there regardless of the executing thread. - LocalConsoleManager, ShellFactoryImpl and SuCommand store the subject on the session so SecuredCommand can read it back. --- .../apache/karaf/jaas/command/SuCommand.java | 3 +- .../console/osgi/LocalConsoleManager.java | 5 +- .../console/osgi/secured/SecuredCommand.java | 20 +++- .../apache/karaf/shell/ssh/ShellCommand.java | 6 -- .../karaf/shell/ssh/ShellFactoryImpl.java | 6 +- .../apache/karaf/util/jaas/JaasHelper.java | 100 ++++-------------- .../internal/servlet/KarafOsgiManager.java | 6 -- 7 files changed, 47 insertions(+), 99 deletions(-) diff --git a/jaas/command/src/main/java/org/apache/karaf/jaas/command/SuCommand.java b/jaas/command/src/main/java/org/apache/karaf/jaas/command/SuCommand.java index 7f49dad7407..5bdfcca7c2d 100644 --- a/jaas/command/src/main/java/org/apache/karaf/jaas/command/SuCommand.java +++ b/jaas/command/src/main/java/org/apache/karaf/jaas/command/SuCommand.java @@ -67,11 +67,12 @@ public Object execute() throws Exception { JaasHelper.doAs(subject, (PrivilegedExceptionAction) () -> { final Session newSession = session.getFactory().create( System.in, System.out, System.err, SuCommand.this.session.getTerminal(), null, null); + newSession.put(Subject.class.getName(), subject); Object oldIgnoreInterrupts = session.get(Session.IGNORE_INTERRUPTS); try { session.put(Session.IGNORE_INTERRUPTS, Boolean.TRUE); String name = "Karaf local console user " + ShellUtil.getCurrentUserName(); - Thread thread = new Thread(newSession, name); + Thread thread = new Thread(() -> JaasHelper.runAs(subject, newSession), name); thread.start(); thread.join(); } finally { diff --git a/shell/core/src/main/java/org/apache/karaf/shell/impl/console/osgi/LocalConsoleManager.java b/shell/core/src/main/java/org/apache/karaf/shell/impl/console/osgi/LocalConsoleManager.java index 8a423b1c495..4632cf1204c 100644 --- a/shell/core/src/main/java/org/apache/karaf/shell/impl/console/osgi/LocalConsoleManager.java +++ b/shell/core/src/main/java/org/apache/karaf/shell/impl/console/osgi/LocalConsoleManager.java @@ -91,14 +91,15 @@ public void close() { encoding, LocalConsoleManager.this::close); session.put(Session.IS_LOCAL, true); + session.put(Subject.class.getName(), subject); registration = bundleContext.registerService(Session.class, session, null); String name = "Karaf local console user " + ShellUtil.getCurrentUserName(); boolean delayconsole = Boolean.parseBoolean(System.getProperty(KARAF_DELAY_CONSOLE)); if (delayconsole) { watcher = new DelayedStarted(session, name, bundleContext, System.in); - new Thread(watcher, name).start(); + new Thread(() -> JaasHelper.runAs(subject, watcher), name).start(); } else { - new Thread(session, name).start(); + new Thread(() -> JaasHelper.runAs(subject, session), name).start(); } return session; }); diff --git a/shell/core/src/main/java/org/apache/karaf/shell/impl/console/osgi/secured/SecuredCommand.java b/shell/core/src/main/java/org/apache/karaf/shell/impl/console/osgi/secured/SecuredCommand.java index 2df6e097fd7..9e48966b0b7 100644 --- a/shell/core/src/main/java/org/apache/karaf/shell/impl/console/osgi/secured/SecuredCommand.java +++ b/shell/core/src/main/java/org/apache/karaf/shell/impl/console/osgi/secured/SecuredCommand.java @@ -18,8 +18,12 @@ */ package org.apache.karaf.shell.impl.console.osgi.secured; +import java.security.PrivilegedActionException; +import java.security.PrivilegedExceptionAction; import java.util.List; +import javax.security.auth.Subject; + import org.apache.felix.gogo.runtime.Closure; import org.apache.felix.gogo.runtime.Token; import org.apache.felix.service.command.CommandSession; @@ -28,6 +32,7 @@ import org.apache.karaf.shell.api.console.Completer; import org.apache.karaf.shell.api.console.Parser; import org.apache.karaf.shell.api.console.Session; +import org.apache.karaf.util.jaas.JaasHelper; public class SecuredCommand implements Command, Function { @@ -64,8 +69,19 @@ public Parser getParser() { @Override public Object execute(Session session, List arguments) throws Exception { - factory.checkSecurity(getScope(), getName(), arguments); - return command.execute(session, arguments); + // Gogo may dispatch this command on a pool thread that never had the session's + // subject bound (Subject.callAs()'s ScopedValue binding does not cross an + // ExecutorService task boundary), so re-bind it here from the session before + // checking permissions or running the command. + Subject subject = (Subject) session.get(Subject.class.getName()); + try { + return JaasHelper.doAs(subject, (PrivilegedExceptionAction) () -> { + factory.checkSecurity(getScope(), getName(), arguments); + return command.execute(session, arguments); + }); + } catch (PrivilegedActionException e) { + throw e.getException(); + } } @Override diff --git a/shell/ssh/src/main/java/org/apache/karaf/shell/ssh/ShellCommand.java b/shell/ssh/src/main/java/org/apache/karaf/shell/ssh/ShellCommand.java index 0023522ed4b..69f8553176d 100644 --- a/shell/ssh/src/main/java/org/apache/karaf/shell/ssh/ShellCommand.java +++ b/shell/ssh/src/main/java/org/apache/karaf/shell/ssh/ShellCommand.java @@ -51,12 +51,6 @@ public class ShellCommand implements Command { private static final Logger LOGGER = LoggerFactory.getLogger(ShellCommand.class); - private static final Class[] SECURITY_BUGFIX = { - JaasHelper.class, - JaasHelper.OsgiSubjectDomainCombiner.class, - JaasHelper.DelegatingProtectionDomain.class, - }; - private String command; private InputStream in; private OutputStream out; diff --git a/shell/ssh/src/main/java/org/apache/karaf/shell/ssh/ShellFactoryImpl.java b/shell/ssh/src/main/java/org/apache/karaf/shell/ssh/ShellFactoryImpl.java index 54487b71447..accaaa22fe8 100644 --- a/shell/ssh/src/main/java/org/apache/karaf/shell/ssh/ShellFactoryImpl.java +++ b/shell/ssh/src/main/java/org/apache/karaf/shell/ssh/ShellFactoryImpl.java @@ -24,6 +24,7 @@ import java.io.OutputStream; import java.io.PrintStream; import java.nio.charset.Charset; +import java.security.PrivilegedAction; import java.util.Map; import javax.security.auth.Subject; @@ -109,8 +110,9 @@ public void start(ChannelSession channelSession, Environment environment) throws shell.put(e.getKey(), e.getValue()); } shell.put(Subject.class.getName(), subject); - JaasHelper.runAs(subject, () -> - new Thread(shell, "Karaf ssh console user " + ShellUtil.getCurrentUserName()).start()); + String threadName = "Karaf ssh console user " + + JaasHelper.doAs(subject, (PrivilegedAction) ShellUtil::getCurrentUserName); + new Thread(() -> JaasHelper.runAs(subject, shell), threadName).start(); } catch (Exception e) { throw new IOException("Unable to start shell", e); } diff --git a/util/src/main/java/org/apache/karaf/util/jaas/JaasHelper.java b/util/src/main/java/org/apache/karaf/util/jaas/JaasHelper.java index d121731081f..f2b53169a5a 100644 --- a/util/src/main/java/org/apache/karaf/util/jaas/JaasHelper.java +++ b/util/src/main/java/org/apache/karaf/util/jaas/JaasHelper.java @@ -14,18 +14,14 @@ */ package org.apache.karaf.util.jaas; -import java.security.AccessControlContext; -import java.security.AccessController; -import java.security.Permission; import java.security.Principal; import java.security.PrivilegedAction; import java.security.PrivilegedActionException; import java.security.PrivilegedExceptionAction; -import java.security.ProtectionDomain; import java.util.Set; +import java.util.concurrent.CompletionException; import javax.security.auth.Subject; -import javax.security.auth.SubjectDomainCombiner; import org.apache.karaf.jaas.boot.principal.RolePrincipal; @@ -89,13 +85,11 @@ public static T doAs(final Subject subject, if (action == null) { throw new NullPointerException(); } - // set up the new Subject-based AccessControlContext for doPrivileged - final AccessControlContext currentAcc = AccessController.getContext(); - final AccessControlContext newAcc = AccessController.doPrivileged - ((PrivilegedAction) () -> new AccessControlContext(currentAcc, - subject != null ? new OsgiSubjectDomainCombiner(subject) : null)); - // call doPrivileged and push this new context on the stack - return AccessController.doPrivileged(action, newAcc); + try { + return Subject.callAs(subject, action::run); + } catch (CompletionException e) { + throw unwrapUnchecked(e); + } } public static T doAs(final Subject subject, @@ -103,79 +97,25 @@ public static T doAs(final Subject subject, if (action == null) { throw new NullPointerException(); } - // set up the new Subject-based AccessControlContext for doPrivileged - final AccessControlContext currentAcc = AccessController.getContext(); - final AccessControlContext newAcc = AccessController.doPrivileged - ((PrivilegedAction) () -> new AccessControlContext(currentAcc, - subject != null ? new OsgiSubjectDomainCombiner(subject) : null)); - // call doPrivileged and push this new context on the stack - return AccessController.doPrivileged(action, newAcc); - } - - public static class OsgiSubjectDomainCombiner extends SubjectDomainCombiner { - - private final Subject subject; - - public OsgiSubjectDomainCombiner(Subject subject) { - super(subject); - this.subject = subject; - } - - public ProtectionDomain[] combine(ProtectionDomain[] currentDomains, - ProtectionDomain[] assignedDomains) { - int cLen = (currentDomains == null ? 0 : currentDomains.length); - int aLen = (assignedDomains == null ? 0 : assignedDomains.length); - ProtectionDomain[] newDomains = new ProtectionDomain[cLen + aLen]; - Principal[] principals = subject.getPrincipals().toArray(new Principal[0]); - for (int i = 0; i < cLen; i++) { - newDomains[i] = new DelegatingProtectionDomain(currentDomains[i], principals); - } - if (assignedDomains != null) { - System.arraycopy(assignedDomains, 0, newDomains, cLen, aLen); - } - return optimize(newDomains); - } - - private ProtectionDomain[] optimize(ProtectionDomain[] domains) { - if (domains == null || domains.length == 0) { - return null; - } - ProtectionDomain[] optimized = new ProtectionDomain[domains.length]; - ProtectionDomain pd; - int num = 0; - for (ProtectionDomain domain : domains) { - if ((pd = domain) != null) { - boolean found = false; - for (int j = 0; j < num && !found; j++) { - found = (optimized[j] == pd); - } - if (!found) { - optimized[num++] = pd; - } - } - } - if (num > 0 && num < domains.length) { - ProtectionDomain[] downSize = new ProtectionDomain[num]; - System.arraycopy(optimized, 0, downSize, 0, downSize.length); - optimized = downSize; + try { + return Subject.callAs(subject, action::run); + } catch (CompletionException e) { + Throwable cause = e.getCause(); + if (cause instanceof Exception && !(cause instanceof RuntimeException)) { + throw new PrivilegedActionException((Exception) cause); } - return ((num == 0 || optimized.length == 0) ? null : optimized); + throw unwrapUnchecked(e); } } - public static class DelegatingProtectionDomain extends ProtectionDomain { - - private final ProtectionDomain delegate; - - DelegatingProtectionDomain(ProtectionDomain delegate, Principal[] principals) { - super(delegate.getCodeSource(), delegate.getPermissions(), delegate.getClassLoader(), principals); - this.delegate = delegate; + private static RuntimeException unwrapUnchecked(CompletionException e) { + Throwable cause = e.getCause(); + if (cause instanceof RuntimeException) { + return (RuntimeException) cause; } - - @Override - public boolean implies(Permission permission) { - return delegate.implies(permission); + if (cause instanceof Error) { + throw (Error) cause; } - + return e; } } diff --git a/webconsole/console/src/main/java/org/apache/felix/webconsole/internal/servlet/KarafOsgiManager.java b/webconsole/console/src/main/java/org/apache/felix/webconsole/internal/servlet/KarafOsgiManager.java index 39e420ccf3d..1eaeae4541a 100644 --- a/webconsole/console/src/main/java/org/apache/felix/webconsole/internal/servlet/KarafOsgiManager.java +++ b/webconsole/console/src/main/java/org/apache/felix/webconsole/internal/servlet/KarafOsgiManager.java @@ -36,12 +36,6 @@ public class KarafOsgiManager extends OsgiManager { private static final long serialVersionUID = 1090035807469459598L; - private static final Class[] SECURITY_BUGFIX = { - JaasHelper.class, - JaasHelper.OsgiSubjectDomainCombiner.class, - JaasHelper.DelegatingProtectionDomain.class, - }; - public static final String SUBJECT_RUN_AS = "karaf.subject.runas"; public KarafOsgiManager(BundleContext bundleContext) { From 051e1a7cbfa9773897a58da13078a6687ffd193f Mon Sep 17 00:00:00 2001 From: Holger Friedrich Date: Sun, 19 Jul 2026 22:55:24 +0200 Subject: [PATCH 5/5] Change thread creation for itests Signed-off-by: Holger Friedrich --- .../main/java/org/apache/karaf/itests/KarafTestSupport.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/itests/common/src/main/java/org/apache/karaf/itests/KarafTestSupport.java b/itests/common/src/main/java/org/apache/karaf/itests/KarafTestSupport.java index c0203a4b993..855fd46ebdc 100644 --- a/itests/common/src/main/java/org/apache/karaf/itests/KarafTestSupport.java +++ b/itests/common/src/main/java/org/apache/karaf/itests/KarafTestSupport.java @@ -416,10 +416,14 @@ private String executeCommand(final String command, final Long timeout, final Lo if (principals.length == 0) { commandFuture = new FutureTask<>(commandCallable); } else { - // If principals are defined, run the command callable via Subject.doAs() + // If principals are defined, run the command callable via Subject.callAs(). + // Gogo dispatches the actual command execution on its own executor thread, which + // does not inherit the ScopedValue binding set up by Subject.callAs() on JDK 25, + // so also store the subject on the session for SecuredCommand to pick back up. commandFuture = new FutureTask<>(() -> { Subject subject = new Subject(); subject.getPrincipals().addAll(Arrays.asList(principals)); + session.put(Subject.class.getName(), subject); return Subject.callAs(subject, (Callable) commandCallable::call); }); }