Skip to content

FELIX-6872 dependencymanager JDK 25 + maven - #581

Open
paulrutter wants to merge 12 commits into
apache:masterfrom
paulrutter:FELIX-6872-dependencymanager-maven
Open

paulrutter wants to merge 12 commits into
apache:masterfrom
paulrutter:FELIX-6872-dependencymanager-maven

Conversation

@paulrutter

@paulrutter paulrutter commented Oct 24, 2026 •

Copy link
Copy Markdown
Contributor

FELIX-6872 - Dependency Manager: JDK 25 support and build with Maven

The Dependency Manager was the only Felix sub-project still built with Gradle and bnd. This PR makes it build and test on current JDKs (17, 21 and 25) and moves it to Maven, like the other sub-projects, so it is built, tested and released the same way.

It is based on the framework JDK 25 work (#433) and contains 12 commits:

  • 8 commits: JDK support: remove the AccessController usage, Java 11 baseline, update the libraries (bnd 7.4.0 and others), build the Dependency Manager in CI, and fix racy integration tests (see below).
  • 4 commits: Maven: build the bundles, run the integration tests, build the samples and the benchmark, remove the Gradle build. Each of them builds on its own.

What changes

  • Bundles: the core, annotation, runtime, shell and lambda bundles are built by the maven-bundle-plugin, with the existing source layout and the same bundle headers. The versions of the exported packages still come from the packageinfo files.

  • Baseline: the API is baselined against the last release (r16). Every exported package is unchanged, so only the bundle versions move, to a new major because the minimum Java version is now 11:

    Bundle r16 New
    org.apache.felix.dependencymanager 4.6.1 5.0.0
    org.apache.felix.dependencymanager.shell 4.0.9 5.0.0
    org.apache.felix.dependencymanager.runtime 4.0.8 5.0.0
    org.apache.felix.dependencymanager.annotation 5.0.2 6.0.0
    org.apache.felix.dependencymanager.lambda 1.2.2 2.0.0
  • OSGi R6: the bundles are compiled against the OSGi R6 API, so their imports stay as they were in r16 (for example org.osgi.framework 1.8). Compiling against R8 would have silently raised that to 1.10.

  • Integration tests: one module per test bundle. They run inside framework 8 with the bnd-testing-maven-plugin, which resolves the runtime (framework, Gogo, Config Admin, Log, Metatype, JUnit) from the Maven dependencies. The runtime tests process their annotations with the annotation bnd plugin.

  • Samples and benchmark: converted to Maven modules. Each sample bundle is built by its own maven-bundle-plugin execution from the same packages as before, with the same headers. They are not installed or deployed (maven.install.skip, maven.deploy.skip).

  • Gradle is gone: the Gradle build and wrapper, the bnd workspace (cnf), the Eclipse project files and the Gradle based release project are removed. The README describes the Maven build. Existing changelog entries are untouched; there is a new entry for the new versions.

  • CI: the Dependency Manager is built in maven-ci.yml (on 17, 21 and 25). The framework, Gogo and Config Admin snapshots of this repository are installed first, because the integration tests run on them.

Test fixes found on the way

Some integration tests were racy and failed on slow runners:

  • FELIX5200_FactoryPidNotRestartedTest published the new component instance after releasing the test thread, and kept calling its steps after the test was over. It now follows the adapter instances instead of counting calls.
  • Config Admin can deliver the same configuration twice, or re-deliver a factory configuration when the factory registers again. The configuration tests now ignore a repeated delivery (ConfigDeliveries), and the test base ignores the harmless error message Config Admin logs when a factory configuration is created but not updated yet.
  • Several configuration tests shared one configuration pid; each now has its own.

Verification

mvn clean verify in dependencymanager (JDK 21) passes: unit tests (62 core, 10 shell), integration tests for all test modules, API baseline (0 errors for the five bundles) and the license check (Apache Rat). The 24 sample and benchmark bundles have the same classes, exports and activators as the Gradle build. CI is green on JDK 17, 21 and 25.

Notes for reviewers

  • The integration tests need the framework 8, Gogo and Config Admin snapshots of this repository. Until those are released the Dependency Manager cannot be released.
  • The test, sample and benchmark modules are not deployed (maven.deploy.skip).
  • The old Gradle release notes in the changelog.txt files still mention Gradle. They describe past releases and were left alone.

🤖 Generated with Claude Code

https://claude.ai/code/session_017MGDWAYvWioowRTBkoQPjA

@paulrutter
paulrutter force-pushed the FELIX-6872-dependencymanager-maven branch 2 times, most recently from 43237e5 to ff3174b Compare October 24, 2026 20:24
@paulrutter
paulrutter marked this pull request as ready for review October 24, 2026 20:27
@paulrutter
paulrutter force-pushed the FELIX-6872-dependencymanager-maven branch 2 times, most recently from 9fab804 to aa83e3b Compare October 24, 2026 21:42
@paulrutter

Copy link
Copy Markdown
Contributor Author

@pderop i need to sync the base branch with master, but apart from that, dependency manager is now building against jdk25 with maven instead of Gradle. Let me know if you have feedback, i gave you access to my fork.

@pderop

pderop commented Oct 25, 2026

Copy link
Copy Markdown
Contributor

Hi @paulrutter,

Thanks a lot for this work, and for giving me access to your fork!

I have to confess something first: over the past weeks I had been working on the same thing in a local branch (moving DM from Gradle to Maven, in my case with the bnd-maven-plugin and the standard Maven layout), but I never announced it on the list. That was my mistake, sorry about that. Your PR covers the same ground, and I'm happy to go with it.

I took some time to review the result, focusing on the released bundles (core, annotation, runtime, shell, lambda):

  • I built them from your branch and compared the generated manifests and jar contents with the r16 release jars: Bundle-SymbolicName, Bundle-Activator, Export-Package (versions and uses:), Import-Package (apart from the aQute.bnd.* ranges of the annotation bundle, which follow the bndlib version) and the runtime's Provide-Capability are identical, and the bundles contain the same classes (except the synthetic/doPrivileged inner classes, as expected). Nice job.
  • I also checked that the baseline actually works: a change in an implementation package passes, a new public method in org.apache.felix.dm fails with Version increase required; detected 4.6.0, suggested 4.7.0, and bumping the packageinfo makes it pass again.

So please go ahead!

@paulrutter

Copy link
Copy Markdown
Contributor Author

Hi @paulrutter,

Thanks a lot for this work, and for giving me access to your fork!

I have to confess something first: over the past weeks I had been working on the same thing in a local branch (moving DM from Gradle to Maven, in my case with the bnd-maven-plugin and the standard Maven layout), but I never announced it on the list. That was my mistake, sorry about that. Your PR covers the same ground, and I'm happy to go with it.

I took some time to review the result, focusing on the released bundles (core, annotation, runtime, shell, lambda):

  • I built them from your branch and compared the generated manifests and jar contents with the r16 release jars: Bundle-SymbolicName, Bundle-Activator, Export-Package (versions and uses:), Import-Package (apart from the aQute.bnd.* ranges of the annotation bundle, which follow the bndlib version) and the runtime's Provide-Capability are identical, and the bundles contain the same classes (except the synthetic/doPrivileged inner classes, as expected). Nice job.
  • I also checked that the baseline actually works: a change in an implementation package passes, a new public method in org.apache.felix.dm fails with Version increase required; detected 4.6.0, suggested 4.7.0, and bumping the packageinfo makes it pass again.

So please go ahead!

Thanks for your swift response! Once the framework and other jdk25 work is merged, I'll go ahead and merge this one.

Would this then become r17? I still don't fully understand how that works together with the independent versioning of the bundles in dm. Is it just a release name for the combination of those separate bundles?

@paulrutter
paulrutter force-pushed the FELIX-6872-dependencymanager-maven branch 3 times, most recently from bbbd252 to f90d9b1 Compare October 25, 2026 18:12
@pderop

pderop commented Oct 25, 2026

Copy link
Copy Markdown
Contributor

Would this then become r17? I still don't fully understand how that works together with the independent versioning of the bundles in dm. Is it just a release name for the combination of those separate bundles?

Yes, rN was just a name for the set of DM bundles released (and voted) together, each bundle keeping its own version.

Back then, we introduced a specific release process for Dependency Manager to accommodate Bndtools. Now that we're moving back to Maven, I think it makes sense to follow the same release process as the other Felix subprojects for consistency. So I'd say we can drop the r17 naming and stick to the standard Felix release process.

If you agree, the r17 mentions in the changelogs (e.g. "r17 is the name of the release as a whole") can then go away as well.

One more thing I noticed: mvn clean install (as opposed to clean verify, which is what the CI runs) fails on the samples module:

[ERROR] Failed to execute goal org.apache.maven.plugins:maven-install-plugin:3.1.1:install (default-install) on project org.apache.felix.dependencymanager.samples: The packaging plugin for this project did not assign a main file to the project but it has attachments. Change packaging to 'pom'.

The default-jar execution is disabled and only classifier jars are attached, so maven-install-plugin 3.x refuses to install the module. The same applies to lambda.samples and benchmark. Since release:perform runs deploy, which goes through the install phase, this would also break the release (if I'm correct, I'm not sure ...).

As these modules are not released anyway, skipping the install next to the existing deploy skip fixes it:

<properties>
    <!-- the samples are not released -->
    <baseline.skip>true</baseline.skip>
    <maven.deploy.skip>true</maven.deploy.skip>
    <maven.install.skip>true</maven.install.skip>
</properties>

in:

  • org.apache.felix.dependencymanager.samples/pom.xml
  • org.apache.felix.dependencymanager.lambda.samples/pom.xml
  • org.apache.felix.dependencymanager.benchmark/pom.xml

With that change, mvn --file dependencymanager/pom.xml clean install succeeds on your current head (f90d9b1a78), with all tests passing.

As I would prefer to let you keep full control of your branch, I'd rather you push the change yourself, if you do agree with me ?

thanks Paul.

@paulrutter
paulrutter force-pushed the FELIX-6872-dependencymanager-maven branch 2 times, most recently from 7f3559b to cf3c721 Compare October 25, 2026 21:22
@paulrutter

Copy link
Copy Markdown
Contributor Author

Thanks for the review! Both points are done and pushed:

  • maven.install.skip is now set next to maven.deploy.skip in the samples, lambda.samples and benchmark poms. mvn install over those modules and the modules they depend on now succeeds.
  • The "r17" naming is gone from the six changelog.txt files. Each bundle's changelog is headed with its own version, and the top-level one is headed "Dependency Manager". Older entries are untouched.

Both changes were folded into the existing commits (samples and Gradle removal), so the branch is still the same four commits and CI is running again.

I'm hunting down a few flaky tests while I'm at it, Claude makes it easy to correct those as i go along.

@pderop

pderop commented Oct 25, 2026

Copy link
Copy Markdown
Contributor

Claude should fix it, if not please share the flaky tests with me, I'll check.

@paulrutter
paulrutter force-pushed the FELIX-6872-dependencymanager-maven branch from cf3c721 to 3b277ed Compare October 26, 2026 08:04
@paulrutter
paulrutter force-pushed the feature/FELIX-6759-Java-25-LTS branch from 7a02bfa to 01aab02 Compare October 26, 2026 08:42
@paulrutter
paulrutter force-pushed the FELIX-6872-dependencymanager-maven branch 2 times, most recently from 5aa3655 to 7322d2d Compare October 26, 2026 15:19
@paulrutter
paulrutter changed the base branch from feature/FELIX-6759-Java-25-LTS to master October 26, 2026 15:20
AccessController and PrivilegedAction are deprecated for removal along
with the SecurityManager. Drop the doPrivileged wrappers in the core
ServiceTracker and in the runtime InvocationUtil.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_017MGDWAYvWioowRTBkoQPjA
…le 9.8.2

Raise the compile target and the test runtime execution environment from
Java 8 to Java 11 and the bundles to new major versions:
dependencymanager 5.0.0, annotation 6.0.0, runtime 5.0.0, shell 5.0.0
and lambda 2.0.0.

Move the build to bnd 7.4.0 and Gradle 9.8.2, so that it runs on current JDKs,
and adapt the Gradle scripts: locate the bnd workspace from the root project
directory, run Apache Rat (0.16.1) through the Gradle ant builder, and do not
fail the plain test task of the bnd integration test projects, whose tests run
in testOSGi. Stop tracking the Gradle build output.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_017MGDWAYvWioowRTBkoQPjA
Build and test the Dependency Manager against the framework 8.0.0, Gogo 1.2.0
and Config Admin 1.10.0 snapshots of this repository. Update the OSGi core,
compendium and annotation artifacts, JUnit 4.13.2, Mockito 5 (with byte-buddy
and objenesis 3.3), Log and Metatype.

Adapt the tests to the newer APIs: implement ServiceReference.adapt and
getProperties and the LoggerFactory methods in the test stubs. Use a unique
configuration pid per integration test, so that the asynchronous deletion of
the configuration of a previous test cannot reach the next one.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_017MGDWAYvWioowRTBkoQPjA
Add the Dependency Manager to the GitHub Actions workflow with its trigger
paths and path filter. It is built with Gradle after the framework, Gogo and
Config Admin snapshots are installed into the local Maven repository, and the
annotation bundle, which is a bnd plugin used by the other projects, is built
first in a separate Gradle invocation.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_017MGDWAYvWioowRTBkoQPjA
…tRestartedTest

Publish the test instance before releasing the test thread, which otherwise
sometimes compared with the previous instance (seen on JDK 17 in CI).

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_017MGDWAYvWioowRTBkoQPjA
…dTest independent of how often Config Admin delivers the configuration

Config Admin sometimes delivers the factory configuration to the factory more
than once, for example when the factory is registered again. The Dependency
Manager then replaces the adapter instance (stop, then a new start), which the
test, which counted the calls, did not expect: it timed out, or its late calls
failed the next test. Follow the adapter instances instead of counting the
calls. Ran 20 times in a row on 2 CPUs without failure, where the old test
failed 2 times out of 12.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_017MGDWAYvWioowRTBkoQPjA
…me configuration in the configuration tests

Config Admin can provide a configuration to a service twice, for example when
the service registers while its configuration is updated. The configuration
tests count the updates they expect, so a repeated delivery of the same
configuration failed them now and then on the CI runners (expected:<2> but
was:<3>). They now ignore a repeated delivery (helper ConfigDeliveries); a lost
configuration still counts.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_017MGDWAYvWioowRTBkoQPjA
…sage about a new factory configuration in the test base

Config Admin logs "Ignoring new configuration pid=..." at error level when a
factory configuration has been created but not updated yet while the factory
registers; it provides the configuration with the update. The test base fails
a test when an error is logged, so this message failed an otherwise passing
runtime integration test now and then on the CI runners. The test bases ignore
this one message, every other logged error still fails the test.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_017MGDWAYvWioowRTBkoQPjA
Add a Maven reactor for the Dependency Manager with the core, annotation,
runtime, shell and lambda bundles, built by the maven-bundle-plugin with the
existing source layout and the same bundle headers as the bnd build. The
versions of the exported packages are still read from the packageinfo files,
and the API is baselined against the last release (r16): every exported
package is unchanged, so only the bundle versions move, to a new major for the
Java 11 baseline (dependencymanager 5.0.0, annotation 6.0.0, runtime 5.0.0,
shell 5.0.0, lambda 2.0.0).

The bundles are compiled against the OSGi R6 API, the lowest one supported, so
their imports stay as they were in r16 (for example org.osgi.framework 1.8).
The test stubs implementing ServiceReference no longer use @OverRide on the
methods that were only added in later releases. The unit tests run with
surefire, and the packageinfo files are excluded from the license check.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_017MGDWAYvWioowRTBkoQPjA
Split the integration test projects into one module per bundle (the itest api,
bundle and bundle2, the filter index tests and its static and dynamic custom
index bundles, the lambda tests and lifecycle bundle, and the runtime tests),
built with the maven-bundle-plugin. The tests run inside framework 8 with the
bnd-testing-maven-plugin, which resolves the runtime (framework 8, Gogo,
Config Admin, Log, Metatype and JUnit) from the Maven dependencies, as the bnd
test runs did. The runtime tests process their annotations with the annotation
bnd plugin.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_017MGDWAYvWioowRTBkoQPjA
…with Maven

Convert the samples, the lambda samples and the benchmark to Maven modules.
Each of their bundles is built by its own execution of the maven-bundle-plugin
from the packages it contained before, with the same headers, so the bundles
are the same as the ones of the bnd build, and the annotation descriptors are
generated for the annotated samples only.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_017MGDWAYvWioowRTBkoQPjA
Remove the Gradle build and wrapper, the bnd workspace, the Eclipse project
files and the Gradle based release project, which the Maven build replaces,
and build the Dependency Manager with Maven in CI. The README describes the
Maven build, and the changelogs get an entry for the new versions, the
existing entries are kept.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_017MGDWAYvWioowRTBkoQPjA
@paulrutter
paulrutter force-pushed the FELIX-6872-dependencymanager-maven branch from 7322d2d to 115ae16 Compare October 26, 2026 17:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants