FELIX-6807 - Java 25 LTS support - #433
Conversation
- Try-out building framework and HTTP subprojects against java 25 to see what will break
- Use 25-ea (Early access)
- Update mockito-core to a version that has jdk 25 support via byte-buddy
- Update awaitility
- Disable jetty bundle
- Don't rely on snapshot build for jetty
|
can you also do a change in scr to trigger this test |
on detail |
Will do tomorrow 👍 |
- continue-on-error: true to allow building other modules after a failed one - Change SCR to trigger CI
|
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. |
Every module whose code changed now documents it where that module already keeps its history: - scr/changelog.txt gains a 2.3.0 entry. - gogo/runtime/doc/changelog.txt gains a 1.1.6 to 1.2.0 entry. - webconsole/README.md gains a 5.1.0 entry under Releases, which is where that project records its history rather than in a separate changelog file. framework/doc/changelog.txt was already updated with the 8.0.0 entry. http is not included: only its test code changed. The webconsole Security section is left alone. It documents HTTP authentication and CSRF, which is unrelated to the Java Security Manager. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
configadmin is not in the workflow's path filters, so a pull request touching only configadmin matches no trigger and gets no build at all. This change would otherwise go in unverified. Adds it to both triggers, to the paths-filter, and as a build step. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
configadmin has the same defect as the other modules here: it declares felix-parent 6
with relativePath ../pom/pom.xml, which does not match the local pom, so Maven
resolves the released felix-parent 6 from Central instead. That parent hardcodes
felix.java.version 7, and javac rejects it:
error: release version 7 not supported
Moving it to felix-parent 9 fixes the build. No production code is changed here, so
no version is bumped.
configadmin was also absent from the workflow's path filters, so a pull request
touching only configadmin matched no trigger and got no build at all. It now has a
filter and a build step.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This reverts commit 45f6d17.
With configadmin building and running in CI, its integration tests reported 34 errors
in ConfigAdminSecurityTest on JDK 21, 23 and 25, all of them:
java.lang.UnsupportedOperationException: The Security Manager is deprecated
and will be removed in a future release
at java.lang.System.setSecurityManager(System.java:431)
at org.apache.felix.framework.Felix.init(Felix.java:674)
The test launches a framework with org.osgi.framework.security set, so Felix.init
tries to install a Security Manager. System.setSecurityManager has thrown since Java
18 unless -Djava.security.manager=allow is passed, and passing that flag is itself a
fatal startup error from Java 24 on (JEP 486). There is no JDK in the matrix above 17
where this test can pass, and the stack shows it is the released framework 7.0.5 that
configadmin tests against, so this is long standing rather than new.
The test class is excluded from the integration test run with that explanation. It
still runs for anyone building on JDK 17.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ocal build
The TCK step failed to resolve the framework:
Could not find artifact org.apache.felix:org.apache.felix.framework:jar:
8.0.0-SNAPSHOT in apache.snapshots
The framework step ran clean verify, which does not install. The TCK is a separate
Maven invocation, so it resolves org.apache.felix.framework from the repository
rather than from the build that just ran. While the framework was 7.1.0-SNAPSHOT that
version existed in apache.snapshots, so resolution succeeded and the TCK quietly
exercised the published snapshot instead of the code under test. Renaming to 8.0.0
turned that silent substitution into a resolution error.
Running clean install makes the TCK test the framework this build produced, which is
what the step was always meant to do.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The paths-filter entry was named log.extension and the step tested
if: steps.changes.outputs.log.extension == 'true'
A dot in a GitHub expression is property access, so that reads the log filter's
output and then looks up an extension property on the resulting string, which is
always null. The condition could never be true, and the step was skipped on every
run, including the runs that changed log.extension/pom.xml.
The filter is renamed to logextension. Its path stays log.extension/**; only the
key, which has to be a plain identifier, changes.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…sion
gogo.runtime moved to 1.2.0-SNAPSHOT, but gogo.jline still declared a dependency on
1.1.7-SNAPSHOT, which no longer exists locally and is not published:
Could not find artifact org.apache.felix:org.apache.felix.gogo.runtime:jar:
1.1.7-SNAPSHOT in apache.snapshots
gogo.jline is the only module referencing the snapshot; gogo.bom and gogo.command
reference the released 1.1.4 and are unaffected.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
main is changed by this branch, its dependency on the framework moves to
8.0.0-SNAPSHOT, and it embeds the framework, yet nothing verified it: there was no
main path filter and no build step, so a break would only have surfaced at release
time.
Building it locally first showed it does not build on a modern JDK at all, for the
same reason as the modules in the split-out build repair change: it declares
felix-parent 6, which does not match the local pom, so Maven resolves the released
parent from Central. That parent brings in ianal-maven-plugin 1.0-alpha-1, which
reflects into java.io and is blocked from Java 16 on:
Unable to make private java.io.File(java.lang.String,java.io.File) accessible:
module java.base does not "opens java.io" to unnamed module
Moving to felix-parent 9 removes ianal but pins maven-antrun-plugin 3.1.0, which
rejects the legacy tasks element:
You are using 'tasks' which has been removed from the maven-antrun-plugin
Both antrun executions now use target instead.
main has no code change, so its version stays at 7.1.0-SNAPSHOT. The step runs after
the framework step, which installs the framework it embeds.
Verified on JDK 25: main builds, the jar embeds the framework, and launching it
starts the framework and keeps running, with no Security Manager error. The only
output is the known sun.misc.Unsafe warning from URLHandlers.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…uild output main bundles the framework, so shipping main 7.1.0 containing framework 8.0.0 would be misleading. Its version moves to 8.0.0-SNAPSHOT alongside the framework. main.distribution is unaffected: it pins framework.version to the released 7.0.5 and consumes published artifacts rather than this build. Also removes six jars totalling 1.7 MB that were committed by mistake in the previous commit. main/bundle is populated by the build, is not tracked on master, and was not ignored, so a plain add picked it up. main/bundle, main/bin and main/conf are now in .gitignore, all three being build output of this module. Verified on JDK 25: main builds at 8.0.0-SNAPSHOT and the build no longer leaves untracked artifacts behind. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
main.distribution copies bundles into its basedir the same way main does, so building it leaves untracked jars behind in bundle/ and bin/. Both are now ignored. main.distribution/conf is tracked and is deliberately not ignored. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…modern-jdk # Conflicts: # .github/workflows/maven-ci.yml
|
@apache/felix-committers please take a look at #433 (comment) and let me know your thoughts on this. I would like to move this JDK 25 thing forward, given it's released for a while now. I does bring the baseline for framework to JDK 9, but given we can still maintain a JDK 8 branch if required, i would think that's acceptable. |
…stances Util.loadDefaultProperties returned the shared static DEFAULTS instance, and its callers write per framework values into the result: initializeJPMSEE stores felix.detect.java.version, and ExtensionManager stores the resolved system package lists with that version baked into each entry. So the first framework created in a JVM stamped its own Java version onto every framework created after it. Two frameworks in one JVM configured with different java.specification.version values would share the first one's system packages. This showed up as ExtensionManagerTest.systemBundleHeaders failing on some JDKs and not others: MultiReleaseVersionTest creates a framework with java.specification.version 9, and when it ran first the later test saw java.lang exported as 0.0.0.JavaSE_009 rather than the running JDK's version. Test order varies between JVMs, which is why it failed on 21 and 23 while passing on 17 and 25. loadDefaultProperties now returns a copy, so each framework computes its own values. Verified on JDK 21 and 25: 121 tests with no errors, and systemBundleHeaders passes when run together with MultiReleaseVersionTest in one JVM. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
JDK 11 as lower bound would be an option too - it will receive updates till next year at least. The libs might be able to use a few new APIs and it might be easier to test, given that running CI against EOL JDK 9 is always a bit awkward. Projects stuck on EOL JDKs typically don't care about dependency updates, otherwise they wouldn't be there in the first place. So the scenario that someone is running JDK 9 && wants to update felix to the latest version is quite unlikely IMO. (I am no committer) |
That's a fair point, but given what i know from other PRs where the baseline was proposed to be lifted, we got some pushback on it. I agree that consumers on older JDK versions can remain to use the 7.x line, while 8.x should lift the baseline. |
I think it will depend on how the lower bound changes though. If its in the next major version while the last major version is still maintained - i can't see how this would cause pushback. My main point was that bumping the lower bound from LTS 8 to EOL 9 (on the next major version) is not much different to bumping it from LTS 8 to LTS 11 - since it isn't 8 anymore in both cases ;) |
FELIX-6759 Follow-up: Make the remaining module builds work on modern JDKs
FELIX-6759 Follow-up: Replace Thread.stop() with interrupt() in configadmin UpdateThread
Try-out building framework and HTTP subprojects against java 25 to see what will break
https://issues.apache.org/jira/browse/FELIX-6807