Repository navigation
FELIX-6807 - Java 25 LTS support - #433
Conversation
|
can you also do a change in scr to trigger this test |
on detail |
Will do tomorrow 👍 |
|
might be interesting to du parallel build for matrix like here in osgi repo |
|
Results of the latest run, including SCR: SCR Framework HTTP |
I discussed this at https://www.mail-archive.com/dev%40felix.apache.org/msg57202.html But I didn't have any luck getting feedback on using a common solution between Equinox and Felix (and maybe others). Therefore I only integrated it into Equinox to get rid of the use of Unsafe for the URL singleton management. If someone from Felix would like to adopt the same strategy as I did in Equinox I think it would be good so the two framework's can live in the same JVM without cratering the URL singletons. |
|
Thanks @tjwatson, from my point of view we should indeed consider adopting the same approach as you mentioned in osgi/osgi#226 (comment). |
|
common solution between Equinox and Felix .... And springboot would be really best way to solve. |
I don't disagree but I have my doubts the SpringBoot URL factories will be open to play well with others. Worth a try if you already have a good contribution relationship with the Spring project to bring up the issue. But I first suggest we get Felix and Equinox to play well with each other to prove out the approach. |
|
In addition to the changes of removing the use of sun.misc.Unsafe, all code in Framework using SecurityManager should be removed, since SecurityManager has been completely disabled from Java 24 onwards. |
|
I disagree with your comment in Security manager. In all cases where Security Managemer is uses we check Existense before we use that. So no execution in Versions where Security Manager is remived. |
|
With the SecurityManager removal, it makes it difficult to support wide JDK LTS version ranges. I suggest making two supported branch streams with JDK LTS version alignment. There are two issues with trying to support a wide range of JDK versions:
The approach we are looking at taking in Apache ActiveMQ and Apache Karaf is to have branches with JDK supported ranges:: branch-a: Supported Java: JDK 17 to 21 (Apache Karaf is able to do JDK 11 to JDK 21) It does to appear that it is physically possible to mismatch JAAS API across JDK 11-25 or JDK 17-25 b/c of the JAAS API change. One side sets a ThreadLocal and uses doAs() and the newer API uses ScopedValue and runAs() methods on the Subject class. see: https://docs.oracle.com/en/java/javase/21/docs/api/java.base/javax/security/auth/Subject.html |
Is the class completely gone? I would be surprised because I would have expected loads of class not founds when running Equinox on Java 25, but we don't observe that. |
|
@mattrpav Just wanted to note that JDT has now new support for multi-release jars that maps nicely to what we have in maven. Multi-Release Jars are a perfect fit for such kind of support such JDK dependent changes, then one only need a |
|
@tjwatson I mispoke-- JDK 25 disables the SecurityManager by default and custom SecurityManages cannot be installed. @laeubi MRJ is a good idea, will check that out. Have you solved for how to do JDK-version-specific unit tests in a single Maven module? If so, I'd love to see a sample configuration. |
Let me know if you need any pointer or support, we would need something similar for equinox on the long run. Regarding testing the most useful these days is a matrix build what uses different native JVMs... of course one can write MR-Test cases as well its just a bit more setup. |
I have a distaste for MRJ. If we create a |
Yeah, the how-to-execute-tests is the issue I'm running into. Creating a MR-jar for compiling and packaging test classes seems straight-forward. The hang-up comes in as far as how to instruct the surefire plugin to execute those tests. ASFAIK, would require two separate Maven profiles (kludgy-- as the surefire configurations would need to be kept in sync b/w the two profiles) for listing include/exclude of class test names based on JDK version. Punting to use separate Maven modules by JDK version seems less than ideal. |
Anything specific? I'm looking at using a MRJ for activemq-client to use that for the Virtual Thread classes that need JDK 21+. |
It has been a while since I looked into them seriously. But the first blocker from me was source code debugging and what the source JAR looks like for the release. It was a nightmare to debug. Maybe all that is fixed by now. But it seemed far more simple to just choose the class to load myself in code. |
But this will only work if the API is not gone (or non existent) if you not choose reflection ... what is a nightmare on its own of course.
As said MR support in JDT is quite new and there is obviously a lot to improve, but if anything is missing it could be linked here: so I can only invite everyone to participate there :-)
While this might work in this case (see above) this is simply not manageable for any more complex API as it would require you to use reflection all the time, that has no compile time checking, it has no real debugging support or anything so not really something I would call "more simple".
The source jar?!? Do you mean the final build jar or the source code in the project? |
This is all theoretical since I also would never recommend using a compiler that doesn't understand the release you are targeting where the class still exists that your code wants to use on old Java versions. Even if/when they really remove the class the Since Oracle just extended their Java 8 support way out to 2030 (and other vendors will follow) I don't see that happening any earlier for the new Java versions being released through 2030. I suspect they will continue to support
I mean the source jar, typically published to maven central. As in org.eclipse.osgi-3.23.200-sources.jar Even if that all works out and all IDEs handle it in a useful way. I often am handed an error log and asked to analyze some stack trace with methods and line numbers. At that point it is nice to just know the version I am dealing with to find the code for the class/method/line-number in the stack trace without having to worry about which "version" of the class within the MRJ got loaded. I am doubtful anyone can convince me that MRJs are a perfect solution for me. |
Even for that I would use a separate project that holds the Java 21+ code that uses Virftual Threads and then pull the classes into the project that still targets the old Java release. Then have code that knows what class to load based on Java versions. That is what we do for the Virtual threads. We then created an For example, this component only gets enabled for Java versions < 21: And this one gets enabled for Java versions >= 21 The rest of the system gets injected with the right component implementation without having to worry about what Java version is running. |
That's an elegant solution to the problem indeed. In Felix, we have resorted to reflection to determine java 21 specific features, see for example To get back to the problem of the SecurityManager in Felix, i feel we've only scratched the surface and are not aligned on the approach to take. The options as i see them:
I don't have a strong preference yet, but i do think we should come up with a plan forward, while also respecting the OSGi spec on the security aspects. |
I don't want to convince anyone, just mentioning that its maybe worth to consider and most of what you describe more feels like limitations of the tooling that could probably be better enhanced there. Compared to that your solution seem to add a lot of complexity both on the build time as well as dev time just to emulate a feature the JVM can already offer to you (you then need to make sure to have at least a MR OSGi-Manifest), but again I don't want to convince anyone and there are obviously multiple ways. The problem of multi-release source jars is discussed here so you maybe want to leave a not if you thing its not feasible (even though you not plan to use it) as likely others might still adopt: |
|
I solved for MRJ usage in ActiveMQ for Virtual Thread support without adding additional Maven modules based on JDK version.
ref: apache/activemq#1504 |
|
org.osgi.framework.BundleException: Unable to resolve com.github.ben-manes.caffeine [15](R 15.0): missing requirement [com.github.ben-manes.caffeine [15](R 15.0)] osgi.ee; (osgi.ee=UNKNOWN) Unresolved requirements: [[com.github.ben-manes.caffeine [15](R 15.0)] osgi.ee; (osgi.ee=UNKNOWN)]
at org.apache.felix.framework.Felix.resolveBundleRevision(Felix.java:4398)
at org.apache.felix.framework.Felix.startBundle(Felix.java:2308)
at org.apache.felix.framework.Felix.setActiveStartLevel(Felix.java:1566)
at org.apache.felix.framework.FrameworkStartLevelImpl.run(FrameworkStartLevelImpl.java:297)
at java.base/java.lang.Thread.run(Thread.java:1474)
Nevermind! The problem is the BND plugin does not yet support JDK-25 and emits an invalid |
I have noticed too. I cannot give any feedback personnally since I am not using Felix. It's another team which does and they are extremely busy right now. We have some dependencies on them, so I am eager to see them move to JDK 25 so they unblock us 😄 Hence why I am monitoring this PR. Many thanks for all your efforts ! |
Btw, we're already running JDK 25 in production with the current Felix framework 7.0.5. As long as you don't use the security manager, you'll only see a few deprecation warnings, but it still runs and works ok. Might be good to keep in mind. |
They are using |
IMO: "support" is an overloaded term. Some use it for "it appears to be working", others rise the bar a little higher. I personally try to use "support" only when CI of that project tests on those JDK versions (at the bare minimum). E.g NetBeans 32 is using felix atm too (supports running on JDK 21, 25 and 27) but it would fail if something uses certain features (even by accident). - java: [17,21,23]
+ java: [17,21,23,25]speaking of versions: I would consider adding |
|
Agreed on both counts, and on the definition — "tested in CI" is a much more useful bar than "seems to work", and it is exactly the gap here: 7.0.5 predates the framework having a CI job at all (FELIX-6765 added it for 7.1.0), so nobody could say what it was tested against. Matrix is now Applying your own rule, 26 comes out too: 27 superseded it in September 2026, so
The framework itself is fine on 26 and 27 — both green including the OSGi Core R8 TCK, checked on the plurl branch (run), where the path filters build only Noting NetBeans 32 runs on 21, 25 and 27 — 27 is the one we cannot cover yet, for the reason above. |
|
Matrix is 27 does fail, but not in anything this PR touches. Aries SpiFly 1.3.7 bundles ASM 9.6, which rejects class file major version 71, so its weaving hook throws for every class it sees and Jetty never finishes starting:
SpiFly 1.3.8 carries ASM 9.10.1, which does declare While digging I also found that the Felix HTTP ITs pin Both are filed as FELIX-6869. Once the first part lands, 27 can go back in the matrix. For the record, the framework itself is fine on 26 and 27 — both green including the OSGi Core R8 TCK, checked on the plurl branch where the path filters build only |
Indeed, I got things mixed up. Thanks again for your comment and work! |
|
@apache/felix-committers i want to move this forward. I would like to ask all committers on this project for feedback. If there is none, i'll move ahead with merging the end of this month and put out the release vote for all impacted projects outlined in #433 (comment). |
Unfortunately don't have much useful to add from our side - we're in the camp of those running 7.0.5 under J 17, 21, and 25 but with a fairly old bundle set. Hopefully at some stage we'll get our Jetty, servlet APIs etc up to newer versions but it's tricky to carve out time with them all basically working. Appreciate your efforts on this though for when we can get to the newer versions. |
I am also in the camp of people running on Java 25 + Felix Framework 7.0.5 with no visibile issues. I am however looking forward to this fix since this is a needed refactoring and having it released means I can run some more comprehensive tests with it. |
Java 24 permanently disabled the SecurityManager (JEP 486), so the OSGi security layer can no longer function. Removes framework.security and the doPrivileged/AccessController plumbing that existed to support it. SecurityManagerEx now resolves the call stack with StackWalker. Co-Authored-By: Claude Opus 5 <[email protected]>
StackWalker needs Java 9, but 9 and 10 are long EOL, so 11 is the first sensible LTS baseline. Removing the security layer is breaking, hence 8.0.0. framework/README.md documents the 7.x / 8.x split. Co-Authored-By: Claude Opus 5 <[email protected]>
Co-Authored-By: Claude Opus 5 <[email protected]>
Co-Authored-By: Claude Opus 5 <[email protected]>
…urrent JDK UpdateThread.terminate() called Thread.stop(), which has thrown UnsupportedOperationException since Java 20; it now interrupts the worker. ConfigAdminSecurityTest is excluded above JDK 17: it needs -Djava.security.manager=allow, a fatal startup error from Java 24 on. Co-Authored-By: Claude Opus 5 <[email protected]>
…nt JDK JDK 20 removed --release 7 and JDK 21 removed --release 6, so configadmin, connect, log.extension, resolver and bundlerepository could not compile on the CI matrix at all. CI did not surface this because those steps only run when the module itself changes. Co-Authored-By: Claude Opus 5 <[email protected]>
Co-Authored-By: Claude Opus 5 <[email protected]>
Co-Authored-By: Claude Opus 5 <[email protected]>
Modules across the repository pin released Felix sibling bundles as dependencies of their tests, so pax-exam and the bnd resolver exercise released artifacts instead of the code in this repository. Regressions introduced here can therefore pass CI unnoticed, which is how the FilterImpl.WrapperCapability bug fixed in FELIX-6869 survived on master. Every such pin becomes a property that still defaults to the latest release, so each module keeps building on its own. CI now builds and installs a producing module whenever it or one of its consumers changed, and overrides the property with the version built here: framework -> configadmin, scr, http, gogo configadmin -> scr utils -> resolver gogo bundles -> gogo itest-shell, itest-jline, jline The two gogo itest modules took their versions from an imported BOM that pins released bundles, so they resolved against none of the code in this repository; they now carry explicit, overridable versions. http/itest kept a 7.0.5 framework pin that FELIX-6869 missed. The step that resolves the versions evaluates the gogo modules inside the gogo reactor, because gogo-parent is not published anywhere. framework.security is left pinned: it is no longer built here (removed in the 8.0.0 framework line, FELIX-6807) and its only consumer, ConfigAdminSecurityTest, is excluded. ipojo is left alone, since its removal is already proposed separately. Co-Authored-By: Claude Opus 5 <[email protected]>
27 was taken out again in d347835 because Aries SpiFly 1.3.7 bundles ASM 9.6, which rejects class file major version 71, so its weaving hook threw for every class and Jetty never finished starting. FELIX-6869 since provisions ASM 9.10.1 alongside the SpiFly bundle, which does know version 71, so the blocker should be gone. The framework and the TCK already passed on 27 when that was checked separately. Co-Authored-By: Claude Opus 5 <[email protected]>
7a02bfa to
01aab02
Compare
FELIX-6870 - Run the integration tests against the code being built
framework, main and bundlerepository each declared an attach-sources
execution of maven-source-plugin with the jar goal. The Apache parent
declares the same execution id with jar-no-fork in its apache-release
profile, and Maven merges executions sharing an id by taking the union of
their goals, so both ran:
<id>attach-sources</id>
<goal>jar</goal>
<goal>jar-no-fork</goal>
Each attached a sources jar, and the second was rejected:
Failed to execute goal maven-source-plugin:3.3.0:jar-no-fork
(attach-sources): We have duplicated artifacts attached.
That only surfaces under -Papache-release, which is why ordinary builds
and CI never hit it, but it fails every release of those three modules.
Use jar-no-fork in all three, as connect already does: the goals then
coincide, the union is a single goal, and sources are attached once
without forking a second lifecycle.
Co-Authored-By: Claude Opus 5 <[email protected]>
The JDK 21 doclet enforces HTML5 and rejects markup that predates it, so maven-javadoc-plugin:jar failed under -Papache-release and blocked a release of these two modules: configadmin 79 errors in 13 files, e.g. <table border="0" cellspacing="3"> gogo.runtime <h1> where the doclet expects a lower heading level The framework already sets failOnError=false for the same reason. Do the same here: the javadoc jar is still produced and attached, the markup is left to be cleaned up separately, and no release is held up by it. This only affects maven-javadoc-plugin; no other part of either build changes. Co-Authored-By: Claude Opus 5 <[email protected]>
Same as the preceding commit, for the last module that still failed under -Papache-release: RepositoryAdmin.java has an unclosed <ol>, which the JDK 21 doclet rejects. bundlerepository is not part of this release, but it would have been blocked the next time it is released, and no module should be left with a known release-blocking javadoc failure. Co-Authored-By: Claude Opus 5 <[email protected]>
Implements FELIX-6807 — make the framework run on current JDKs, up to and including Java 25 — and FELIX-6870, which makes the integration tests run against the code being built (merged in from #573).
Overview
JEP 486 permanently disabled the
SecurityManagerin Java 24: it can no longer be installed, and-Djava.security.manager=allowis a fatal startup error. The OSGi security layer cannot work under that, so this PR removes it and everything that depended on it, then raises the build baselines so every module still compiles on a current JDK.The framework becomes 8.0.0, a deliberately breaking release. The 7.x line stays as the Java 8 + security-layer option.
81 files changed, 654 insertions(+), 8331 deletions(-)— overwhelmingly deletions.The bulk of it:
framework.securityis deleted outright.SecureActionloses ~1,600 lines: everydoPrivilegedwrapper collapses to a direct call.AccessController/System.getSecurityManager()/doPrivilegedusage is removed from the framework, SCR and Web Console.SecurityManagerExis reduced to aStackWalker-based call-stack lookup.Affected bundles
frameworkSecureActionreduced to direct calls;SecurityManagerExnow usesStackWalker; baseline 8 → 117.1.0-SNAPSHOT→8.0.0-SNAPSHOTframework.security2.9.0-SNAPSHOTframework.tck7.1.0→7.4.0; runs against framework8.0.0-SNAPSHOTconfigadminUpdateThread.terminate()no longer callsThread.stop()(throws since Java 20) — it interrupts instead;ConfigAdminSecurityTestexcluded above JDK 171.9.27-SNAPSHOT→1.10.0-SNAPSHOTscrdoPrivileged/SecurityManagerremoved fromDependencyManager,RegionConfigurationSupport,AbstractComponentManager,BaseMethod,FieldUtils2.2.19-SNAPSHOT→2.3.0-SNAPSHOTwebconsoledoPrivileged/SecurityManagerremoved fromAbstractWebConsolePlugin,OsgiManager,ConfigurationSupport5.0.19-SNAPSHOT→5.1.0-SNAPSHOTmain8.0.0-SNAPSHOT7.1.0-SNAPSHOT→8.0.0-SNAPSHOTgogoThreadUtilsno longer consults theSecurityManager; Mockito5.17.0→5.18.01.1.7-SNAPSHOT→1.2.0-SNAPSHOThttp5.17.0→5.18.0, Awaitility4.2.1→4.3.0(base, jetty, jetty12, sslfilter, wrappers)resolver,connect,bundlerepository,log.extensionexamplessource/target1.5→8[17, 21, 25, 27]; 23 dropped (EOL); producers built before their consumers (FELIX-6870)scr,webconsoleandgogo.runtimetake a minor bump rather than a patch: dropping the security-layer code paths is a behavioural change, not a fix.Testing against the code being built (FELIX-6870)
Merged in from #573. Several modules pinned released Felix bundles as dependencies of their tests, so pax-exam and the bnd resolver exercised published artifacts instead of the code in this repository — which is how the
FilterImpl.WrapperCapabilityregression fixed in #554 survived on master unnoticed.Each pin becomes a property that still defaults to the latest release, so every module keeps building standalone. CI builds and installs a producing module whenever it or one of its consumers changed, then overrides the property with the version built here:
frameworkconfigadmin,scr,http/itest,gogoitestsconfigadminscrutilsresolvergogobundlesgogo/jline,itest-shell,itest-jlineTwo cases worth calling out:
http/iteststill pinned framework 7.0.5 — missed by FELIX-6869, which only coveredjettyandjetty12.gogoitest modules resolved against none of the code in this repository: they take versions from an imported BOM that pins released bundles, and the import was itself stale (gogo.bom:1.0.3-SNAPSHOTagainst1.0.7-SNAPSHOTin the reactor).The version-resolving CI step evaluates the gogo modules inside the gogo reactor, because
gogo-parent:7-SNAPSHOTis not published anywhere and a standalonehelp:evaluatewould fail on a clean runner.framework.securitystays pinned at 2.8.3: it is no longer built here, and its only consumer,ConfigAdminSecurityTest, is already excluded. ipojo is left alone, since its removal is proposed separately.JDK baseline changes
Effective
felix.java.versionper module, before and after:frameworkconfigadminconnectlog.extensionmaven.compiler1.7→8)resolverfelix.java.version6 droppedbundlerepositoryexamplessource/targetmainscrwebconsoleOnly the framework's
8 → 11is a policy decision. The rest are forced:--release 7was removed in JDK 20 and--release 6in JDK 21, soconfigadmin,connect,log.extension,resolverandbundlerepositorycould not compile on JDK 21 or 25 at all. CI did not surface this because those steps only run when the module itself changes, and none had changed in a long time.For the framework specifically,
StackWalkerrequires Java 9, but 9 and 10 are long EOL, so 11 is the first sensible LTS baseline.Breaking changes
framework.securityis no longer built or released, andorg.osgi.framework.securityhas no effect.Require-Capability: osgi.eemoves fromJavaSE 1.8toJavaSE 11for the framework.framework/README.mddocuments the 7.x / 8.x split so the choice is discoverable from the repository.