From 3e2e5ff60fb190d8c64dd82a7a1c5b1b68e3171a Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 24 Oct 2026 19:12:32 +0000 Subject: [PATCH 1/8] FELIX-6872 - Dependency Manager: remove AccessController usage 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 Claude-Session: https://claude.ai/code/session_017MGDWAYvWioowRTBkoQPjA --- .../apache/felix/dm/runtime/InvocationUtil.java | 11 +---------- .../apache/felix/dm/tracker/ServiceTracker.java | 14 +++----------- 2 files changed, 4 insertions(+), 21 deletions(-) diff --git a/dependencymanager/org.apache.felix.dependencymanager.runtime/src/org/apache/felix/dm/runtime/InvocationUtil.java b/dependencymanager/org.apache.felix.dependencymanager.runtime/src/org/apache/felix/dm/runtime/InvocationUtil.java index fb4456ba09..55581f8d06 100644 --- a/dependencymanager/org.apache.felix.dependencymanager.runtime/src/org/apache/felix/dm/runtime/InvocationUtil.java +++ b/dependencymanager/org.apache.felix.dependencymanager.runtime/src/org/apache/felix/dm/runtime/InvocationUtil.java @@ -22,8 +22,6 @@ import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.lang.reflect.Proxy; -import java.security.AccessController; -import java.security.PrivilegedAction; /** * Java reflexion utility methods. @@ -90,14 +88,7 @@ public static Object invokeMethod(Object object, final Method m = clazz.getDeclaredMethod(name, signature); if (!(isSuper && Modifier.isPrivate(m.getModifiers()))) { - AccessController.doPrivileged(new PrivilegedAction() - { - public Object run() - { - m.setAccessible(true); - return null; - } - }); + m.setAccessible(true); return m.invoke(object, parameters[i]); } } diff --git a/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/tracker/ServiceTracker.java b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/tracker/ServiceTracker.java index 9148a5d005..55df178e50 100644 --- a/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/tracker/ServiceTracker.java +++ b/dependencymanager/org.apache.felix.dependencymanager/src/org/apache/felix/dm/tracker/ServiceTracker.java @@ -15,8 +15,6 @@ * limitations under the License. */ -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.HashMap; import java.util.Iterator; import java.util.LinkedHashMap; @@ -259,15 +257,9 @@ public ServiceTracker(final BundleContext context, final Filter filter, this.context = context; this.trackReference = null; this.trackClass = null; - final Version frameworkVersion = (Version) AccessController - .doPrivileged(new PrivilegedAction() { - public Version run() { - String version = context - .getProperty(Constants.FRAMEWORK_VERSION); - return (version == null) ? Version.emptyVersion - : new Version(version); - } - }); + final String version = context.getProperty(Constants.FRAMEWORK_VERSION); + final Version frameworkVersion = (version == null) ? Version.emptyVersion + : new Version(version); final boolean endMatchSupported = (frameworkVersion .compareTo(endMatchVersion) >= 0); this.listenerFilter = endMatchSupported ? filter.toString() : null; From e4cd9a122039c7b068d869b20e0a9545e5d7d7e0 Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 24 Oct 2026 19:12:49 +0000 Subject: [PATCH 2/8] FELIX-6872 - Dependency Manager: Java 11 baseline, bnd 7.4.0 and Gradle 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 Claude-Session: https://claude.ai/code/session_017MGDWAYvWioowRTBkoQPjA --- dependencymanager/.gitignore | 3 ++ .../.gradle-wrapper/gradle-wrapper.properties | 2 +- dependencymanager/build.gradle | 8 ++++ dependencymanager/cnf/build.bnd | 4 +- dependencymanager/cnf/ext/libraries.bnd | 2 +- dependencymanager/cnf/repository.mvn | 4 +- dependencymanager/gradle.properties | 4 +- .../bnd.bnd | 2 +- .../bnd.bnd | 4 +- .../bnd.bnd | 2 +- .../bnd.bnd | 2 +- .../bnd.bnd | 6 +-- .../bnd.bnd | 8 ++-- .../bnd.bnd | 2 +- .../bnd.bnd | 2 +- .../bnd.bnd | 2 +- .../bnd.bnd | 2 +- dependencymanager/release/build.gradle | 11 ++--- dependencymanager/release/rat.gradle | 48 ++++++++++--------- 19 files changed, 64 insertions(+), 54 deletions(-) diff --git a/dependencymanager/.gitignore b/dependencymanager/.gitignore index de001d36b8..43e206aada 100644 --- a/dependencymanager/.gitignore +++ b/dependencymanager/.gitignore @@ -6,3 +6,6 @@ /RemoteSystemsTempFiles/ /rat-report.xml +/build/ +/cnf/localrepo/ +/cnf/releaserepo/ diff --git a/dependencymanager/.gradle-wrapper/gradle-wrapper.properties b/dependencymanager/.gradle-wrapper/gradle-wrapper.properties index e65df494a7..8364c22200 100644 --- a/dependencymanager/.gradle-wrapper/gradle-wrapper.properties +++ b/dependencymanager/.gradle-wrapper/gradle-wrapper.properties @@ -20,4 +20,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.8-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.8.2-bin.zip diff --git a/dependencymanager/build.gradle b/dependencymanager/build.gradle index 71ae1fde12..8219eef85e 100644 --- a/dependencymanager/build.gradle +++ b/dependencymanager/build.gradle @@ -20,3 +20,11 @@ tasks.named('wrapper') { jarFile = rootProject.file('.gradle-wrapper/gradle-wrapper.jar') } + +// The bnd launcher based integration tests run in the testOSGi task, so the plain +// Gradle test task of those projects legitimately has no tests to discover. +subprojects { + tasks.withType(Test).configureEach { + failOnNoDiscoveredTests = false + } +} diff --git a/dependencymanager/cnf/build.bnd b/dependencymanager/cnf/build.bnd index b5144dc788..fc975a5a95 100644 --- a/dependencymanager/cnf/build.bnd +++ b/dependencymanager/cnf/build.bnd @@ -58,8 +58,8 @@ # # Java parameters # -javac.source: 1.8 -javac.target: 1.8 +javac.source: 11 +javac.target: 11 # # Removes some headers in order to reduce binary diff between same bundles that are not changed between subsequent releases. diff --git a/dependencymanager/cnf/ext/libraries.bnd b/dependencymanager/cnf/ext/libraries.bnd index 9148780069..b5a801065a 100644 --- a/dependencymanager/cnf/ext/libraries.bnd +++ b/dependencymanager/cnf/ext/libraries.bnd @@ -53,7 +53,7 @@ webconsole=\ ## # bndlib -bndlib=biz.aQute.bndlib;version=5.2.0 +bndlib=biz.aQute.bndlib;version=7.4.0 ## # mockito diff --git a/dependencymanager/cnf/repository.mvn b/dependencymanager/cnf/repository.mvn index 46d73cba8c..0c8d0e3e50 100644 --- a/dependencymanager/cnf/repository.mvn +++ b/dependencymanager/cnf/repository.mvn @@ -16,8 +16,8 @@ # ant:ant:1.5 -biz.aQute.bnd:biz.aQute.bnd.gradle:5.2.0 -biz.aQute.bnd:biz.aQute.bndlib:5.2.0 +biz.aQute.bnd:biz.aQute.bnd.gradle:7.4.0 +biz.aQute.bnd:biz.aQute.bndlib:7.4.0 org.apache.felix:org.apache.felix.framework:5.6.10 org.apache.felix:org.apache.felix.eventadmin:1.4.4 org.apache.felix:org.apache.felix.gogo.command:1.0.2 diff --git a/dependencymanager/gradle.properties b/dependencymanager/gradle.properties index 35354fb51e..a36e805284 100644 --- a/dependencymanager/gradle.properties +++ b/dependencymanager/gradle.properties @@ -17,9 +17,9 @@ * under the License. */ -bnd_version=5.2.0 +bnd_version=7.4.0 # bnd_plugin is the dependency declaration for the bnd gradle plugin -bnd_plugin=biz.aQute.bnd:biz.aQute.bnd.gradle:5.2.0 +bnd_plugin=biz.aQute.bnd:biz.aQute.bnd.gradle:7.4.0 org.gradle.jvmargs=-Xmx2g diff --git a/dependencymanager/org.apache.felix.dependencymanager.annotation/bnd.bnd b/dependencymanager/org.apache.felix.dependencymanager.annotation/bnd.bnd index 9d04b269de..9216cbf839 100644 --- a/dependencymanager/org.apache.felix.dependencymanager.annotation/bnd.bnd +++ b/dependencymanager/org.apache.felix.dependencymanager.annotation/bnd.bnd @@ -14,7 +14,7 @@ # See the License for the specific language governing permissions and # limitations under the License. # -Bundle-Version: 5.0.3 +Bundle-Version: 6.0.0 -buildpath: \ osgi.core;version=6.0,\ osgi.cmpn;version=6.0,\ diff --git a/dependencymanager/org.apache.felix.dependencymanager.benchmark/bnd.bnd b/dependencymanager/org.apache.felix.dependencymanager.benchmark/bnd.bnd index 57c6346496..a4dd40d2bc 100644 --- a/dependencymanager/org.apache.felix.dependencymanager.benchmark/bnd.bnd +++ b/dependencymanager/org.apache.felix.dependencymanager.benchmark/bnd.bnd @@ -14,8 +14,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # -javac.source: 1.8 -javac.target: 1.8 +javac.source: 11 +javac.target: 11 Bundle-Version: 1.0.0 -buildpath: \ org.apache.felix.dependencymanager;version=latest,\ diff --git a/dependencymanager/org.apache.felix.dependencymanager.index.itest/bnd.bnd b/dependencymanager/org.apache.felix.dependencymanager.index.itest/bnd.bnd index 48b9256ed0..bd299c32dd 100644 --- a/dependencymanager/org.apache.felix.dependencymanager.index.itest/bnd.bnd +++ b/dependencymanager/org.apache.felix.dependencymanager.index.itest/bnd.bnd @@ -26,7 +26,7 @@ org.apache.felix.dependencymanager.index.itest.tests;version=latest,\ org.apache.felix.gogo.runtime;version=1.0.6 --runee: JavaSE-1.8 +-runee: JavaSE-11 -runvm: -ea -runfw: org.apache.felix.framework;version='[5.6.10,5.6.10]' -buildpath: \ diff --git a/dependencymanager/org.apache.felix.dependencymanager.itest/bnd.bnd b/dependencymanager/org.apache.felix.dependencymanager.itest/bnd.bnd index 3005063c94..600cfd2e54 100644 --- a/dependencymanager/org.apache.felix.dependencymanager.itest/bnd.bnd +++ b/dependencymanager/org.apache.felix.dependencymanager.itest/bnd.bnd @@ -26,7 +26,7 @@ org.apache.felix.gogo.runtime;version=1.0.6,\ org.apache.felix.gogo.shell,\ org.apache.felix.gogo.command --runee: JavaSE-1.8 +-runee: JavaSE-11 -runvm: -ea -runfw: org.apache.felix.framework;version='[5.6.10,5.6.10]' -buildpath: \ diff --git a/dependencymanager/org.apache.felix.dependencymanager.lambda.itest/bnd.bnd b/dependencymanager/org.apache.felix.dependencymanager.lambda.itest/bnd.bnd index 118cfb1551..2e4831cf42 100644 --- a/dependencymanager/org.apache.felix.dependencymanager.lambda.itest/bnd.bnd +++ b/dependencymanager/org.apache.felix.dependencymanager.lambda.itest/bnd.bnd @@ -33,13 +33,13 @@ org.apache.felix.dependencymanager.lambda;version=latest,\ org.apache.felix.gogo.runtime;version=1.0.6 --runee: JavaSE-1.8 +-runee: JavaSE-11 -runfw: org.apache.felix.framework;version='[5.6.10,5.6.10]' -runvm: -ea Bundle-Version: 0.0.0.${tstamp} Test-Cases: ${classes;CONCRETE;EXTENDS;junit.framework.TestCase} -javac.source: 1.8 -javac.target: 1.8 +javac.source: 11 +javac.target: 11 # all tests are configured to assume that dependencies are required by default -runproperties: \ diff --git a/dependencymanager/org.apache.felix.dependencymanager.lambda/bnd.bnd b/dependencymanager/org.apache.felix.dependencymanager.lambda/bnd.bnd index 604546bb1b..c5e5ca3fc2 100644 --- a/dependencymanager/org.apache.felix.dependencymanager.lambda/bnd.bnd +++ b/dependencymanager/org.apache.felix.dependencymanager.lambda/bnd.bnd @@ -14,9 +14,9 @@ # See the License for the specific language governing permissions and # limitations under the License. # -javac.source: 1.8 -javac.target: 1.8 -Bundle-Version: 1.2.3 +javac.source: 11 +javac.target: 11 +Bundle-Version: 2.0.0 -buildpath: \ org.apache.felix.dependencymanager;version=latest,\ osgi.core;version=6.0,\ @@ -26,6 +26,6 @@ Export-Package: \ org.apache.felix.dm.lambda,\ org.apache.felix.dm.lambda.callbacks -runfw: org.apache.felix.framework;version='[4.4.1,4.4.1]' --runee: JavaSE-1.8 +-runee: JavaSE-11 Private-Package: org.apache.felix.dm.lambda.impl Include-Resource: META-INF/=resources/,META-INF/changelog.txt=changelog.txt diff --git a/dependencymanager/org.apache.felix.dependencymanager.runtime.itest/bnd.bnd b/dependencymanager/org.apache.felix.dependencymanager.runtime.itest/bnd.bnd index 239126ee5b..5927e12365 100644 --- a/dependencymanager/org.apache.felix.dependencymanager.runtime.itest/bnd.bnd +++ b/dependencymanager/org.apache.felix.dependencymanager.runtime.itest/bnd.bnd @@ -34,7 +34,7 @@ org.apache.felix.dependencymanager;version=latest,\ org.apache.felix.dependencymanager.runtime;version=latest,\ org.apache.felix.dependencymanager.shell;version=latest --runee: JavaSE-1.7 +-runee: JavaSE-11 -runfw: org.apache.felix.framework;version='[5.6.10,5.6.10]' -runsystempackages: \ sun.reflect diff --git a/dependencymanager/org.apache.felix.dependencymanager.runtime/bnd.bnd b/dependencymanager/org.apache.felix.dependencymanager.runtime/bnd.bnd index 7236438f9d..def3055b76 100644 --- a/dependencymanager/org.apache.felix.dependencymanager.runtime/bnd.bnd +++ b/dependencymanager/org.apache.felix.dependencymanager.runtime/bnd.bnd @@ -14,7 +14,7 @@ # See the License for the specific language governing permissions and # limitations under the License. # -Bundle-Version: 4.0.9 +Bundle-Version: 5.0.0 -buildpath: \ osgi.core;version=4.2,\ osgi.cmpn;version=4.2,\ diff --git a/dependencymanager/org.apache.felix.dependencymanager.shell/bnd.bnd b/dependencymanager/org.apache.felix.dependencymanager.shell/bnd.bnd index 957d03bf5e..46c403552a 100644 --- a/dependencymanager/org.apache.felix.dependencymanager.shell/bnd.bnd +++ b/dependencymanager/org.apache.felix.dependencymanager.shell/bnd.bnd @@ -24,7 +24,7 @@ Private-Package: \ org.apache.felix.dm.shell Bundle-Activator:org.apache.felix.dm.shell.Activator -Bundle-Version: 4.0.10 +Bundle-Version: 5.0.0 Include-Resource: META-INF/=resources/,META-INF/changelog.txt=changelog.txt Bundle-Name: Apache Felix Dependency Manager Shell Bundle-Description: Gogo Shell commands for Apache Felix Dependency Manager diff --git a/dependencymanager/org.apache.felix.dependencymanager/bnd.bnd b/dependencymanager/org.apache.felix.dependencymanager/bnd.bnd index 26ec2d9672..69670ad170 100644 --- a/dependencymanager/org.apache.felix.dependencymanager/bnd.bnd +++ b/dependencymanager/org.apache.felix.dependencymanager/bnd.bnd @@ -34,7 +34,7 @@ Export-Package: \ Include-Resource: META-INF/=resources/,META-INF/changelog.txt=changelog.txt Import-Package: !org.junit,!org.mockito.*,org.osgi.framework;version="[1.8, 2)",* Bundle-Activator: org.apache.felix.dm.impl.Activator -Bundle-Version: 4.6.2 +Bundle-Version: 5.0.0 Bundle-Name: Apache Felix Dependency Manager Bundle-Description: Provides dynamic service and component dependency management Bundle-License: http://www.apache.org/licenses/LICENSE-2.0.txt diff --git a/dependencymanager/release/build.gradle b/dependencymanager/release/build.gradle index db781b0390..abf3c108f4 100644 --- a/dependencymanager/release/build.gradle +++ b/dependencymanager/release/build.gradle @@ -44,19 +44,14 @@ ext.svnReleasePath = "https://dist.apache.org/repos/dist/release/felix" apply plugin: 'java' apply from: file("rat.gradle") -// Add bnd as a build dependency -buildscript { - dependencies { - classpath files('cnf/gradle/biz.aQute.bnd.gradle.jar') - } -} - // Configure RAT plugin to ignore some files rat { excludes = [ 'rat-report.xml', '**/.git/**', '**/.gradle/**', + 'build/**', + '**/.keepme', '**/.project', '**/.settings/**', '**/*.iml', @@ -82,7 +77,7 @@ rat { // Setup the workspace Workspace workspace -workspace = Workspace.getWorkspace(".") +workspace = Workspace.getWorkspace(rootProject.projectDir) task makeStaging { doLast { diff --git a/dependencymanager/release/rat.gradle b/dependencymanager/release/rat.gradle index a15d798d87..0a572f2baf 100644 --- a/dependencymanager/release/rat.gradle +++ b/dependencymanager/release/rat.gradle @@ -20,7 +20,8 @@ import org.gradle.api.Plugin import org.gradle.api.Project import org.gradle.api.Task -import org.gradle.api.internal.project.IsolatedAntBuilder +import org.gradle.api.tasks.Input +import org.gradle.api.tasks.Internal apply plugin: RatPlugin @@ -28,20 +29,24 @@ class RatTask extends DefaultTask { @Input List excludes - def reportPath = '.' - def xmlReport = reportPath + '/rat-report.xml' + // Directory which is checked, and the file the xml report is written to. + @Internal + File baseDir - def generateXmlReport(File reportDir) { - def antBuilder = services.get(IsolatedAntBuilder) - def ratClasspath = project.configurations.rat - antBuilder.withClasspath(ratClasspath).execute { - ant.taskdef(resource: 'org/apache/rat/anttasks/antlib.xml') - ant.report(format: 'xml', reportFile: xmlReport) { - fileset(dir: ".") { - patternset { - excludes.each { - exclude(name: it) - } + @Internal + File xmlReport + + def generateXmlReport() { + xmlReport.parentFile.mkdirs() + def ratClasspath = project.configurations.rat.asPath + def ratExcludes = excludes + def checkedDir = baseDir + project.ant.taskdef(resource: 'org/apache/rat/anttasks/antlib.xml', classpath: ratClasspath) + project.ant.report(format: 'xml', reportFile: xmlReport.absolutePath) { + fileset(dir: checkedDir.absolutePath) { + patternset { + ratExcludes.each { + exclude(name: it) } } } @@ -49,7 +54,7 @@ class RatTask extends DefaultTask { } def printUnknownFiles() { - def ratXml = new XmlParser().parse(xmlReport) + def ratXml = new groovy.xml.XmlParser().parse(xmlReport) ratXml.resource.each { resource -> if (resource.'license-approval'.@name[0] == "false") { println('Unknown license: ' + resource.@name) @@ -59,11 +64,7 @@ class RatTask extends DefaultTask { @TaskAction def rat() { - File reportDir = new File(reportPath) - if (!reportDir.exists()) { - reportDir.mkdirs() - } - generateXmlReport(reportDir) + generateXmlReport() printUnknownFiles() } } @@ -75,7 +76,10 @@ class RatPlugin implements Plugin { Task ratTask = project.task("rat", type: RatTask, group: 'Build', - description: 'Runs Apache Rat checks.') + description: 'Runs Apache Rat checks.') { + baseDir = project.rootProject.projectDir + xmlReport = new File(project.rootProject.projectDir, 'build/rat-report.xml') + } project.tasks[JavaBasePlugin.CHECK_TASK_NAME].dependsOn ratTask } @@ -87,7 +91,7 @@ class RatPlugin implements Plugin { mavenCentral() } project.dependencies { - rat 'org.apache.rat:apache-rat-tasks:0.8' + rat 'org.apache.rat:apache-rat-tasks:0.16.1' } } } From 9c70143d71b0a5ecdeb16ca95b3ba90126a3db43 Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 24 Oct 2026 19:12:50 +0000 Subject: [PATCH 3/8] FELIX-6872 - Dependency Manager: update libraries and adapt the tests 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 Claude-Session: https://claude.ai/code/session_017MGDWAYvWioowRTBkoQPjA --- dependencymanager/cnf/ext/junit.bnd | 2 +- dependencymanager/cnf/ext/libraries.bnd | 31 +++++++++++-------- dependencymanager/cnf/repository.mvn | 30 +++++++++--------- .../bnd.bnd | 6 ++-- .../bnd.bnd | 4 +-- .../bnd.bnd | 18 +++++------ .../felix/dm/index/itest/tests/TestBase.java | 25 +++++++++++++++ .../bnd.bnd | 24 +++++++------- .../api/ConfigurationDependencyTest.java | 3 +- ...8_TypeSafeConfigWithDefaultMethodTest.java | 3 +- ...dateMissedIfComponentIsRestartingTest.java | 3 +- .../OptionalConfigurationDependencyTest.java | 3 +- .../apache/felix/dm/itest/util/TestBase.java | 25 +++++++++++++++ .../bnd.bnd | 22 +++++++------ .../felix/dm/lambda/itest/TestBase.java | 25 +++++++++++++++ .../bnd.bnd | 4 +-- .../bnd.bnd | 8 ++--- .../bnd.bnd | 24 +++++++------- .../bnd.bnd | 4 +-- .../bnd.bnd | 8 ++--- .../bnd.bnd | 8 ++--- .../apache/felix/dm/tracker/TrackedTest.java | 12 +++++++ ...ultiPropertyFilterIndexReferencedTest.java | 12 +++++++ .../test/test/TestReference.java | 12 +++++++ 24 files changed, 222 insertions(+), 94 deletions(-) diff --git a/dependencymanager/cnf/ext/junit.bnd b/dependencymanager/cnf/ext/junit.bnd index 129c585689..99bc945e5f 100644 --- a/dependencymanager/cnf/ext/junit.bnd +++ b/dependencymanager/cnf/ext/junit.bnd @@ -15,5 +15,5 @@ # limitations under the License. # -junit: org.apache.servicemix.bundles.junit; version=4.12 +junit: org.apache.servicemix.bundles.junit; version=4.13.2 test-reports: test-results diff --git a/dependencymanager/cnf/ext/libraries.bnd b/dependencymanager/cnf/ext/libraries.bnd index b5a801065a..2bcb86467a 100644 --- a/dependencymanager/cnf/ext/libraries.bnd +++ b/dependencymanager/cnf/ext/libraries.bnd @@ -17,25 +17,25 @@ ## # metatype service -metatype=org.apache.felix.metatype;version=1.0.4 +metatype=org.apache.felix.metatype;version=1.2.4 ## # log service -log=org.apache.felix.log;version=1.0.1 +log=org.apache.felix.log;version=1.3.2 ## # Gogo bundles gogo=\ - org.apache.felix.gogo.command;version=1.0.2,\ - org.apache.felix.gogo.runtime;version=1.0.10,\ - org.apache.felix.gogo.shell;version=1.0.0,\ - org.jline;version=3.0.4,\ + org.apache.felix.gogo.command;version=latest,\ + org.apache.felix.gogo.runtime;version=latest,\ + org.apache.felix.gogo.shell;version=latest,\ + org.jline;version=3.29.0,\ org.fusesource.jansi;version=1.16.0 ## # Configuration Admin -configadmin=org.apache.felix.configadmin;version=1.8.8 +configadmin=org.apache.felix.configadmin;version=latest ## # Event Admin @@ -57,21 +57,26 @@ bndlib=biz.aQute.bndlib;version=7.4.0 ## # mockito -mockito=org.mockito.mockito-core;version=1.10.19 +mockito=\ + org.mockito.mockito-core;version=5.24.0,\ + net.bytebuddy.byte-buddy;version=1.17.7,\ + net.bytebuddy.byte-buddy-agent;version=1.17.7 ## # objenesis -objenesis=org.objenesis;version=2.2 +objenesis=org.objenesis;version=3.3 ## # runtime dependencies used by integration tests # itest.run=\ - org.apache.servicemix.bundles.junit;version=4.12,\ - org.mockito.mockito-core;version='[1.10.19,1.10.20)',\ - org.objenesis;version='[2.2.0,2.2.1)' + org.apache.servicemix.bundles.junit;version=4.13.2,\ + org.mockito.mockito-core;version='[5.24.0,5.25)',\ + net.bytebuddy.byte-buddy;version='[1.17.7,1.18)',\ + net.bytebuddy.byte-buddy-agent;version='[1.17.7,1.18)',\ + org.objenesis;version='[3.3.0,3.3.1)' ## # Felix Framework # -felix.framework=org.apache.felix.framework;version='[5.6.10,5.6.10]' +felix.framework=org.apache.felix.framework;version='[8.0.0,9)' diff --git a/dependencymanager/cnf/repository.mvn b/dependencymanager/cnf/repository.mvn index 0c8d0e3e50..ebebab0bbf 100644 --- a/dependencymanager/cnf/repository.mvn +++ b/dependencymanager/cnf/repository.mvn @@ -18,17 +18,17 @@ ant:ant:1.5 biz.aQute.bnd:biz.aQute.bnd.gradle:7.4.0 biz.aQute.bnd:biz.aQute.bndlib:7.4.0 -org.apache.felix:org.apache.felix.framework:5.6.10 +org.apache.felix:org.apache.felix.framework:8.0.0-SNAPSHOT org.apache.felix:org.apache.felix.eventadmin:1.4.4 -org.apache.felix:org.apache.felix.gogo.command:1.0.2 -org.apache.felix:org.apache.felix.gogo.shell:1.0.0 -org.apache.felix:org.apache.felix.gogo.runtime:1.0.10 -org.jline:jline:3.0.4 +org.apache.felix:org.apache.felix.gogo.command:1.1.3-SNAPSHOT +org.apache.felix:org.apache.felix.gogo.shell:1.1.5-SNAPSHOT +org.apache.felix:org.apache.felix.gogo.runtime:1.2.0-SNAPSHOT +org.jline:jline:3.29.0 org.apache.felix:org.apache.felix.http.api:3.0.0 org.apache.felix:org.apache.felix.http.servlet-api:1.1.2 -org.apache.felix:org.apache.felix.configadmin:1.8.8 -org.apache.felix:org.apache.felix.log:1.0.1 -org.apache.felix:org.apache.felix.metatype:1.1.2 +org.apache.felix:org.apache.felix.configadmin:1.10.0-SNAPSHOT +org.apache.felix:org.apache.felix.log:1.3.2 +org.apache.felix:org.apache.felix.metatype:1.2.4 org.apache.felix:org.apache.felix.http.jetty:3.4.8 org.apache.felix:org.apache.felix.webconsole:4.3.4 org.apache.felix:org.apache.felix.dependencymanager:4.6.1 @@ -37,12 +37,14 @@ org.apache.felix:org.apache.felix.dependencymanager.lambda:1.2.2 org.apache.felix:org.apache.felix.dependencymanager.runtime:4.0.8 org.apache.felix:org.apache.felix.dependencymanager.shell:4.0.9 org.jline:jline-builtins:3.3.0 -org.apache.servicemix.bundles:org.apache.servicemix.bundles.junit:4.12_1 -org.mockito:mockito-core:1.10.19 -org.objenesis:objenesis:2.2 -org.osgi:osgi.annotation:6.0.1 -org.osgi:osgi.cmpn:6.0.0 -org.osgi:osgi.core:6.0.0 +org.apache.servicemix.bundles:org.apache.servicemix.bundles.junit:4.13.2_1 +org.mockito:mockito-core:5.24.0 +net.bytebuddy:byte-buddy:1.17.7 +net.bytebuddy:byte-buddy-agent:1.17.7 +org.objenesis:objenesis:3.3 +org.osgi:osgi.annotation:8.1.0 +org.osgi:osgi.cmpn:7.0.0 +org.osgi:osgi.core:8.0.0 biz.aQute.bnd:biz.aQute.bnd.annotation:3.5.0 org.slf4j:slf4j-simple:1.7.7 org.slf4j:slf4j-api:1.7.7 diff --git a/dependencymanager/org.apache.felix.dependencymanager.annotation/bnd.bnd b/dependencymanager/org.apache.felix.dependencymanager.annotation/bnd.bnd index 9216cbf839..06ad54cc73 100644 --- a/dependencymanager/org.apache.felix.dependencymanager.annotation/bnd.bnd +++ b/dependencymanager/org.apache.felix.dependencymanager.annotation/bnd.bnd @@ -16,9 +16,9 @@ # Bundle-Version: 6.0.0 -buildpath: \ - osgi.core;version=6.0,\ - osgi.cmpn;version=6.0,\ - biz.aQute.bndlib;version=3.5 + osgi.core;version=8.0,\ + osgi.cmpn;version=7.0,\ + biz.aQute.bndlib;version=7.4.0 Private-Package: org.apache.felix.dm.annotation.plugin.bnd Export-Package: org.apache.felix.dm.annotation.api Include-Resource: META-INF/=resources/,META-INF/changelog.txt=changelog.txt diff --git a/dependencymanager/org.apache.felix.dependencymanager.benchmark/bnd.bnd b/dependencymanager/org.apache.felix.dependencymanager.benchmark/bnd.bnd index a4dd40d2bc..4b0f4eb236 100644 --- a/dependencymanager/org.apache.felix.dependencymanager.benchmark/bnd.bnd +++ b/dependencymanager/org.apache.felix.dependencymanager.benchmark/bnd.bnd @@ -19,8 +19,8 @@ javac.target: 11 Bundle-Version: 1.0.0 -buildpath: \ org.apache.felix.dependencymanager;version=latest,\ - osgi.core;version=6.0,\ - osgi.cmpn;version=6.0 + osgi.core;version=8.0,\ + osgi.cmpn;version=7.0 -sub: \ *.bnd diff --git a/dependencymanager/org.apache.felix.dependencymanager.index.itest/bnd.bnd b/dependencymanager/org.apache.felix.dependencymanager.index.itest/bnd.bnd index bd299c32dd..8efac4401d 100644 --- a/dependencymanager/org.apache.felix.dependencymanager.index.itest/bnd.bnd +++ b/dependencymanager/org.apache.felix.dependencymanager.index.itest/bnd.bnd @@ -15,27 +15,27 @@ # limitations under the License. # -runbundles: \ - org.apache.servicemix.bundles.junit;version=4.12,\ - org.apache.felix.metatype;version=1.1.2,\ - org.apache.felix.log;version=1.0.1,\ - org.apache.felix.configadmin;version=1.8.8,\ + org.apache.servicemix.bundles.junit;version=4.13.2,\ + org.apache.felix.metatype;version=1.2.4,\ + org.apache.felix.log;version=1.3.2,\ + org.apache.felix.configadmin;version=latest,\ org.apache.felix.dependencymanager;version=latest,\ org.apache.felix.dependencymanager.shell;version=latest,\ org.apache.felix.dependencymanager.index.itest.dynamic.customindex;version=latest,\ org.apache.felix.dependencymanager.index.itest.static.customindex;version=latest,\ org.apache.felix.dependencymanager.index.itest.tests;version=latest,\ - org.apache.felix.gogo.runtime;version=1.0.6 + org.apache.felix.gogo.runtime;version=latest -runee: JavaSE-11 -runvm: -ea --runfw: org.apache.felix.framework;version='[5.6.10,5.6.10]' +-runfw: org.apache.felix.framework;version='[8.0.0,9)' -buildpath: \ - osgi.core;version=6.0,\ - osgi.cmpn;version=6.0,\ + osgi.core;version=8.0,\ + osgi.cmpn;version=7.0,\ org.apache.felix.dependencymanager;version=latest,\ org.apache.felix.dependencymanager.shell;version=latest,\ ${junit},\ - org.apache.felix.gogo.runtime;version=1.0 + org.apache.felix.gogo.runtime;version=latest -runsystempackages: \ sun.reflect Test-Cases: \ diff --git a/dependencymanager/org.apache.felix.dependencymanager.index.itest/src/org/apache/felix/dm/index/itest/tests/TestBase.java b/dependencymanager/org.apache.felix.dependencymanager.index.itest/src/org/apache/felix/dm/index/itest/tests/TestBase.java index 36a98fe7a8..edda18832d 100644 --- a/dependencymanager/org.apache.felix.dependencymanager.index.itest/src/org/apache/felix/dm/index/itest/tests/TestBase.java +++ b/dependencymanager/org.apache.felix.dependencymanager.index.itest/src/org/apache/felix/dm/index/itest/tests/TestBase.java @@ -223,6 +223,31 @@ protected void sleep(int ms) { return (Dictionary) properties; } + @Override + public org.osgi.service.log.Logger getLogger(String name) { + return null; + } + + @Override + public org.osgi.service.log.Logger getLogger(Class clazz) { + return null; + } + + @Override + public L getLogger(Bundle bundle, String name, Class loggerType) { + return null; + } + + @Override + public L getLogger(String name, Class loggerType) { + return null; + } + + @Override + public L getLogger(Class clazz, Class loggerType) { + return null; + } + public void log(int level, String message) { checkError(level, null); if (LOG_LEVEL >= level) { diff --git a/dependencymanager/org.apache.felix.dependencymanager.itest/bnd.bnd b/dependencymanager/org.apache.felix.dependencymanager.itest/bnd.bnd index 600cfd2e54..a3f4efab51 100644 --- a/dependencymanager/org.apache.felix.dependencymanager.itest/bnd.bnd +++ b/dependencymanager/org.apache.felix.dependencymanager.itest/bnd.bnd @@ -15,27 +15,29 @@ # limitations under the License. # -runbundles: \ - org.apache.servicemix.bundles.junit;version=4.12,\ - org.mockito.mockito-core;version='[1.10.19,1.10.20)',\ - org.objenesis;version='[2.2.0,2.2.1)',\ - org.apache.felix.metatype;version=1.1.2,\ - org.apache.felix.log;version=1.0.1,\ - org.apache.felix.configadmin;version=1.8.8,\ + org.apache.servicemix.bundles.junit;version=4.13.2,\ + org.mockito.mockito-core;version='[5.24.0,5.25)',\ + net.bytebuddy.byte-buddy;version='[1.17.7,1.18)',\ + net.bytebuddy.byte-buddy-agent;version='[1.17.7,1.18)',\ + org.objenesis;version='[3.3.0,3.3.1)',\ + org.apache.felix.metatype;version=1.2.4,\ + org.apache.felix.log;version=1.3.2,\ + org.apache.felix.configadmin;version=latest,\ org.apache.felix.dependencymanager;version=latest,\ org.apache.felix.dependencymanager.shell;version=latest,\ - org.apache.felix.gogo.runtime;version=1.0.6,\ + org.apache.felix.gogo.runtime;version=latest,\ org.apache.felix.gogo.shell,\ org.apache.felix.gogo.command -runee: JavaSE-11 -runvm: -ea --runfw: org.apache.felix.framework;version='[5.6.10,5.6.10]' +-runfw: org.apache.felix.framework;version='[8.0.0,9)' -buildpath: \ - osgi.core;version=6.0,\ - osgi.cmpn;version=6.0,\ + osgi.core;version=8.0,\ + osgi.cmpn;version=7.0,\ org.apache.felix.dependencymanager;version=latest,\ org.apache.felix.dependencymanager.shell;version=latest,\ ${junit},\ - org.apache.felix.gogo.runtime;version=1.0 + org.apache.felix.gogo.runtime;version=latest -runsystempackages: \ sun.reflect -sub: \ diff --git a/dependencymanager/org.apache.felix.dependencymanager.itest/src/org/apache/felix/dm/itest/api/ConfigurationDependencyTest.java b/dependencymanager/org.apache.felix.dependencymanager.itest/src/org/apache/felix/dm/itest/api/ConfigurationDependencyTest.java index 23ab0d1924..1303851340 100644 --- a/dependencymanager/org.apache.felix.dependencymanager.itest/src/org/apache/felix/dm/itest/api/ConfigurationDependencyTest.java +++ b/dependencymanager/org.apache.felix.dependencymanager.itest/src/org/apache/felix/dm/itest/api/ConfigurationDependencyTest.java @@ -40,7 +40,8 @@ */ @SuppressWarnings({"unchecked", "rawtypes"}) public class ConfigurationDependencyTest extends TestBase { - final static String PID = "ConfigurationDependencyTest.pid"; + // Unique per test, so that the asynchronous deletion of the configuration of a previous test cannot reach the next one. + final String PID = "ConfigurationDependencyTest.pid." + System.nanoTime(); /** * Tests that we can provision a type-safe configuration to a component. diff --git a/dependencymanager/org.apache.felix.dependencymanager.itest/src/org/apache/felix/dm/itest/api/FELIX5238_TypeSafeConfigWithDefaultMethodTest.java b/dependencymanager/org.apache.felix.dependencymanager.itest/src/org/apache/felix/dm/itest/api/FELIX5238_TypeSafeConfigWithDefaultMethodTest.java index 3c8c92eb59..fe05d9b344 100644 --- a/dependencymanager/org.apache.felix.dependencymanager.itest/src/org/apache/felix/dm/itest/api/FELIX5238_TypeSafeConfigWithDefaultMethodTest.java +++ b/dependencymanager/org.apache.felix.dependencymanager.itest/src/org/apache/felix/dm/itest/api/FELIX5238_TypeSafeConfigWithDefaultMethodTest.java @@ -34,7 +34,8 @@ * @author Felix Project Team */ public class FELIX5238_TypeSafeConfigWithDefaultMethodTest extends TestBase { - final static String PID = "ConfigurationDependencyTest.pid"; + // Unique per test, so that the asynchronous deletion of the configuration of a previous test cannot reach the next one. + final String PID = "FELIX5238_TypeSafeConfigWithDefaultMethodTest.pid." + System.nanoTime(); /** * Tests that we can provision a type-safe config annotation to a component. diff --git a/dependencymanager/org.apache.felix.dependencymanager.itest/src/org/apache/felix/dm/itest/api/FELIX5243_ConfigUpdateMissedIfComponentIsRestartingTest.java b/dependencymanager/org.apache.felix.dependencymanager.itest/src/org/apache/felix/dm/itest/api/FELIX5243_ConfigUpdateMissedIfComponentIsRestartingTest.java index ed7762c4df..1d3a206c5d 100644 --- a/dependencymanager/org.apache.felix.dependencymanager.itest/src/org/apache/felix/dm/itest/api/FELIX5243_ConfigUpdateMissedIfComponentIsRestartingTest.java +++ b/dependencymanager/org.apache.felix.dependencymanager.itest/src/org/apache/felix/dm/itest/api/FELIX5243_ConfigUpdateMissedIfComponentIsRestartingTest.java @@ -45,7 +45,8 @@ * @author Felix Project Team */ public class FELIX5243_ConfigUpdateMissedIfComponentIsRestartingTest extends TestBase { - final static String PID = "ConfigurationDependencyTest.pid"; + // Unique per test, so that the asynchronous deletion of the configuration of a previous test cannot reach the next one. + final String PID = "FELIX5243_ConfigUpdateMissedIfComponentIsRestartingTest.pid." + System.nanoTime(); public void testOptionalConfigurationConsumer() throws InterruptedException { DependencyManager m = getDM(); diff --git a/dependencymanager/org.apache.felix.dependencymanager.itest/src/org/apache/felix/dm/itest/api/OptionalConfigurationDependencyTest.java b/dependencymanager/org.apache.felix.dependencymanager.itest/src/org/apache/felix/dm/itest/api/OptionalConfigurationDependencyTest.java index 9be16c0255..cc8c834cc7 100644 --- a/dependencymanager/org.apache.felix.dependencymanager.itest/src/org/apache/felix/dm/itest/api/OptionalConfigurationDependencyTest.java +++ b/dependencymanager/org.apache.felix.dependencymanager.itest/src/org/apache/felix/dm/itest/api/OptionalConfigurationDependencyTest.java @@ -40,7 +40,8 @@ * @author Felix Project Team */ public class OptionalConfigurationDependencyTest extends TestBase { - final static String PID = "ConfigurationDependencyTest.pid"; + // Unique per test, so that the asynchronous deletion of the configuration of a previous test cannot reach the next one. + final String PID = "OptionalConfigurationDependencyTest.pid." + System.nanoTime(); public void testOptionalConfigurationConsumer() { DependencyManager m = getDM(); diff --git a/dependencymanager/org.apache.felix.dependencymanager.itest/src/org/apache/felix/dm/itest/util/TestBase.java b/dependencymanager/org.apache.felix.dependencymanager.itest/src/org/apache/felix/dm/itest/util/TestBase.java index 78da1484a0..6873f9c98d 100644 --- a/dependencymanager/org.apache.felix.dependencymanager.itest/src/org/apache/felix/dm/itest/util/TestBase.java +++ b/dependencymanager/org.apache.felix.dependencymanager.itest/src/org/apache/felix/dm/itest/util/TestBase.java @@ -222,6 +222,31 @@ protected void sleep(int ms) { return (Dictionary) properties; } + @Override + public org.osgi.service.log.Logger getLogger(String name) { + return null; + } + + @Override + public org.osgi.service.log.Logger getLogger(Class clazz) { + return null; + } + + @Override + public L getLogger(Bundle bundle, String name, Class loggerType) { + return null; + } + + @Override + public L getLogger(String name, Class loggerType) { + return null; + } + + @Override + public L getLogger(Class clazz, Class loggerType) { + return null; + } + public void log(int level, String message) { checkError(level, null); if (LOG_LEVEL >= level) { diff --git a/dependencymanager/org.apache.felix.dependencymanager.lambda.itest/bnd.bnd b/dependencymanager/org.apache.felix.dependencymanager.lambda.itest/bnd.bnd index 2e4831cf42..c2b0020695 100644 --- a/dependencymanager/org.apache.felix.dependencymanager.lambda.itest/bnd.bnd +++ b/dependencymanager/org.apache.felix.dependencymanager.lambda.itest/bnd.bnd @@ -19,22 +19,24 @@ org.apache.felix.dependencymanager.shell;version=latest,\ org.apache.felix.dependencymanager.lambda;version=latest,\ ${junit},\ - osgi.core;version=6.0,\ - osgi.cmpn;version=6.0 + osgi.core;version=8.0,\ + osgi.cmpn;version=7.0 -runbundles: \ - org.apache.servicemix.bundles.junit;version=4.12,\ - org.mockito.mockito-core;version='[1.10.19,1.10.20)',\ - org.objenesis;version='[2.2.0,2.2.1)',\ - org.apache.felix.metatype;version=1.0.10,\ - org.apache.felix.log;version=1.0.1,\ + org.apache.servicemix.bundles.junit;version=4.13.2,\ + org.mockito.mockito-core;version='[5.24.0,5.25)',\ + net.bytebuddy.byte-buddy;version='[1.17.7,1.18)',\ + net.bytebuddy.byte-buddy-agent;version='[1.17.7,1.18)',\ + org.objenesis;version='[3.3.0,3.3.1)',\ + org.apache.felix.metatype;version=1.2.4,\ + org.apache.felix.log;version=1.3.2,\ org.apache.felix.dependencymanager;version=latest,\ org.apache.felix.dependencymanager.shell;version=latest,\ - org.apache.felix.configadmin;version=1.8.8,\ + org.apache.felix.configadmin;version=latest,\ org.apache.felix.dependencymanager.lambda;version=latest,\ - org.apache.felix.gogo.runtime;version=1.0.6 + org.apache.felix.gogo.runtime;version=latest -runee: JavaSE-11 --runfw: org.apache.felix.framework;version='[5.6.10,5.6.10]' +-runfw: org.apache.felix.framework;version='[8.0.0,9)' -runvm: -ea Bundle-Version: 0.0.0.${tstamp} Test-Cases: ${classes;CONCRETE;EXTENDS;junit.framework.TestCase} diff --git a/dependencymanager/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/lambda/itest/TestBase.java b/dependencymanager/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/lambda/itest/TestBase.java index efc034e034..2cbc24dba9 100644 --- a/dependencymanager/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/lambda/itest/TestBase.java +++ b/dependencymanager/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/lambda/itest/TestBase.java @@ -216,6 +216,31 @@ protected void sleep(int ms) { } } + @Override + public org.osgi.service.log.Logger getLogger(String name) { + return null; + } + + @Override + public org.osgi.service.log.Logger getLogger(Class clazz) { + return null; + } + + @Override + public L getLogger(Bundle bundle, String name, Class loggerType) { + return null; + } + + @Override + public L getLogger(String name, Class loggerType) { + return null; + } + + @Override + public L getLogger(Class clazz, Class loggerType) { + return null; + } + public void log(int level, String message) { checkError(level, null); if (LOG_LEVEL >= level) { diff --git a/dependencymanager/org.apache.felix.dependencymanager.lambda.samples/bnd.bnd b/dependencymanager/org.apache.felix.dependencymanager.lambda.samples/bnd.bnd index 5b5b5a1066..559acfb89e 100644 --- a/dependencymanager/org.apache.felix.dependencymanager.lambda.samples/bnd.bnd +++ b/dependencymanager/org.apache.felix.dependencymanager.lambda.samples/bnd.bnd @@ -2,8 +2,8 @@ org.apache.felix.dependencymanager.lambda;version=latest,\ org.apache.felix.dependencymanager;version=latest,\ org.apache.felix.gogo.runtime;version=latest,\ - osgi.core;version=6.0,\ - osgi.cmpn;version=6.0,\ + osgi.core;version=8.0,\ + osgi.cmpn;version=7.0,\ biz.aQute.bnd.annotation Bundle-Version: 0.0.0.${tstamp} diff --git a/dependencymanager/org.apache.felix.dependencymanager.lambda/bnd.bnd b/dependencymanager/org.apache.felix.dependencymanager.lambda/bnd.bnd index c5e5ca3fc2..c0fc44827e 100644 --- a/dependencymanager/org.apache.felix.dependencymanager.lambda/bnd.bnd +++ b/dependencymanager/org.apache.felix.dependencymanager.lambda/bnd.bnd @@ -19,13 +19,13 @@ javac.target: 11 Bundle-Version: 2.0.0 -buildpath: \ org.apache.felix.dependencymanager;version=latest,\ - osgi.core;version=6.0,\ - osgi.cmpn;version=6.0,\ - osgi.annotation;version=6.0.1 + osgi.core;version=8.0,\ + osgi.cmpn;version=7.0,\ + osgi.annotation;version=8.1 Export-Package: \ org.apache.felix.dm.lambda,\ org.apache.felix.dm.lambda.callbacks --runfw: org.apache.felix.framework;version='[4.4.1,4.4.1]' +-runfw: org.apache.felix.framework;version='[8.0.0,9)' -runee: JavaSE-11 Private-Package: org.apache.felix.dm.lambda.impl Include-Resource: META-INF/=resources/,META-INF/changelog.txt=changelog.txt diff --git a/dependencymanager/org.apache.felix.dependencymanager.runtime.itest/bnd.bnd b/dependencymanager/org.apache.felix.dependencymanager.runtime.itest/bnd.bnd index 5927e12365..cfc781e5f8 100644 --- a/dependencymanager/org.apache.felix.dependencymanager.runtime.itest/bnd.bnd +++ b/dependencymanager/org.apache.felix.dependencymanager.runtime.itest/bnd.bnd @@ -20,22 +20,24 @@ org.apache.felix.dependencymanager;version=latest,\ org.apache.felix.dependencymanager.runtime;version=latest,\ org.apache.felix.dependencymanager.itest.api;version=latest,\ - osgi.core;version=6.0,\ - osgi.cmpn;version=6.0 + osgi.core;version=8.0,\ + osgi.cmpn;version=7.0 -runbundles: \ - org.apache.servicemix.bundles.junit;version=4.12,\ - org.mockito.mockito-core;version='[1.10.19,1.10.20)',\ - org.objenesis;version='[2.2.0,2.2.1)',\ - org.apache.felix.metatype;version=1.1.2,\ - org.apache.servicemix.bundles.junit;version=4.12,\ - org.apache.felix.configadmin;version=1.8.8,\ - org.apache.felix.gogo.runtime;version=1.0.6,\ - org.apache.felix.log;version=1.0.1,\ + org.apache.servicemix.bundles.junit;version=4.13.2,\ + org.mockito.mockito-core;version='[5.24.0,5.25)',\ + net.bytebuddy.byte-buddy;version='[1.17.7,1.18)',\ + net.bytebuddy.byte-buddy-agent;version='[1.17.7,1.18)',\ + org.objenesis;version='[3.3.0,3.3.1)',\ + org.apache.felix.metatype;version=1.2.4,\ + org.apache.servicemix.bundles.junit;version=4.13.2,\ + org.apache.felix.configadmin;version=latest,\ + org.apache.felix.gogo.runtime;version=latest,\ + org.apache.felix.log;version=1.3.2,\ org.apache.felix.dependencymanager;version=latest,\ org.apache.felix.dependencymanager.runtime;version=latest,\ org.apache.felix.dependencymanager.shell;version=latest -runee: JavaSE-11 --runfw: org.apache.felix.framework;version='[5.6.10,5.6.10]' +-runfw: org.apache.felix.framework;version='[8.0.0,9)' -runsystempackages: \ sun.reflect -runvm:-ea diff --git a/dependencymanager/org.apache.felix.dependencymanager.samples/bnd.bnd b/dependencymanager/org.apache.felix.dependencymanager.samples/bnd.bnd index 0c8e16ebd8..1b2d1769f3 100644 --- a/dependencymanager/org.apache.felix.dependencymanager.samples/bnd.bnd +++ b/dependencymanager/org.apache.felix.dependencymanager.samples/bnd.bnd @@ -21,8 +21,8 @@ Bundle-Version: 1.0.0.${tstamp} org.apache.felix.gogo.runtime;version=latest,\ org.apache.felix.dependencymanager.runtime;version=latest,\ org.apache.felix.dependencymanager.annotation;version=latest,\ - osgi.core;version=6.0,\ - osgi.cmpn;version=6.0 + osgi.core;version=8.0,\ + osgi.cmpn;version=7.0 -sub: \ *.bnd -metatype: * diff --git a/dependencymanager/org.apache.felix.dependencymanager.shell/bnd.bnd b/dependencymanager/org.apache.felix.dependencymanager.shell/bnd.bnd index 46c403552a..a266661fda 100644 --- a/dependencymanager/org.apache.felix.dependencymanager.shell/bnd.bnd +++ b/dependencymanager/org.apache.felix.dependencymanager.shell/bnd.bnd @@ -18,9 +18,9 @@ ${mockito},\ org.apache.felix.dependencymanager;version=latest,\ ${junit},\ - osgi.core;version=6.0,\ - osgi.cmpn;version=6.0,\ - org.apache.felix.gogo.runtime;version=1.0 + osgi.core;version=8.0,\ + osgi.cmpn;version=7.0,\ + org.apache.felix.gogo.runtime;version=latest Private-Package: \ org.apache.felix.dm.shell Bundle-Activator:org.apache.felix.dm.shell.Activator @@ -34,4 +34,4 @@ Bundle-Vendor: The Apache Software Foundation -testpath: \ ${junit},\ ${mockito},\ - org.objenesis;version=2.2 + org.objenesis;version=3.3 diff --git a/dependencymanager/org.apache.felix.dependencymanager/bnd.bnd b/dependencymanager/org.apache.felix.dependencymanager/bnd.bnd index 69670ad170..8be859759b 100644 --- a/dependencymanager/org.apache.felix.dependencymanager/bnd.bnd +++ b/dependencymanager/org.apache.felix.dependencymanager/bnd.bnd @@ -17,9 +17,9 @@ -buildpath: \ ${mockito},\ ${junit},\ - osgi.core;version=6.0,\ - osgi.cmpn;version=6.0,\ - osgi.annotation;version=6.0 + osgi.core;version=8.0,\ + osgi.cmpn;version=7.0,\ + osgi.annotation;version=8.1 Private-Package: \ org.apache.felix.dm.impl,\ org.apache.felix.dm.impl.index,\ @@ -45,7 +45,7 @@ Bundle-Category: osgi -testpath: \ ${junit},\ ${mockito},\ - org.objenesis;version=2.2 + org.objenesis;version=3.3 diff --git a/dependencymanager/org.apache.felix.dependencymanager/test/org/apache/felix/dm/tracker/TrackedTest.java b/dependencymanager/org.apache.felix.dependencymanager/test/org/apache/felix/dm/tracker/TrackedTest.java index 5b12dbce96..432e27045b 100644 --- a/dependencymanager/org.apache.felix.dependencymanager/test/org/apache/felix/dm/tracker/TrackedTest.java +++ b/dependencymanager/org.apache.felix.dependencymanager/test/org/apache/felix/dm/tracker/TrackedTest.java @@ -255,6 +255,18 @@ public Bundle getBundle() { return null; } + @Override + @SuppressWarnings("rawtypes") + public java.util.Dictionary getProperties() { + return null; + } + + @Override + @SuppressWarnings("rawtypes") + public Object adapt(Class type) { + return null; + } + @Override public Bundle[] getUsingBundles() { return null; diff --git a/dependencymanager/org.apache.felix.dependencymanager/test/test/MultiPropertyFilterIndexReferencedTest.java b/dependencymanager/org.apache.felix.dependencymanager/test/test/MultiPropertyFilterIndexReferencedTest.java index 1fd8fd044c..aff6950240 100644 --- a/dependencymanager/org.apache.felix.dependencymanager/test/test/MultiPropertyFilterIndexReferencedTest.java +++ b/dependencymanager/org.apache.felix.dependencymanager/test/test/MultiPropertyFilterIndexReferencedTest.java @@ -281,6 +281,18 @@ public Bundle getBundle() { return null; } + @Override + @SuppressWarnings("rawtypes") + public java.util.Dictionary getProperties() { + return null; + } + + @Override + @SuppressWarnings("rawtypes") + public Object adapt(Class type) { + return null; + } + @Override public Bundle[] getUsingBundles() { return null; diff --git a/dependencymanager/org.apache.felix.dependencymanager/test/test/TestReference.java b/dependencymanager/org.apache.felix.dependencymanager/test/test/TestReference.java index 73ebc6bea1..a90c702eb4 100644 --- a/dependencymanager/org.apache.felix.dependencymanager/test/test/TestReference.java +++ b/dependencymanager/org.apache.felix.dependencymanager/test/test/TestReference.java @@ -69,6 +69,18 @@ public Bundle getBundle() { return null; } + @Override + @SuppressWarnings("rawtypes") + public java.util.Dictionary getProperties() { + return null; + } + + @Override + @SuppressWarnings("rawtypes") + public Object adapt(Class type) { + return null; + } + @Override public Bundle[] getUsingBundles() { return null; From 36168cfdb90f65420397b6cc6e37f47c86ce9f78 Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 24 Oct 2026 19:12:50 +0000 Subject: [PATCH 4/8] FELIX-6872 - Build the Dependency Manager in CI 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 Claude-Session: https://claude.ai/code/session_017MGDWAYvWioowRTBkoQPjA --- .github/workflows/maven-ci.yml | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/.github/workflows/maven-ci.yml b/.github/workflows/maven-ci.yml index 68e223727d..d569185557 100644 --- a/.github/workflows/maven-ci.yml +++ b/.github/workflows/maven-ci.yml @@ -23,6 +23,7 @@ on: - 'log.extension/**' - 'examples/**' - 'configadmin/**' + - 'dependencymanager/**' pull_request: branches: [ "master", "feature/**", "maintenance/**" ] paths: @@ -45,6 +46,7 @@ on: - 'log.extension/**' - 'examples/**' - 'configadmin/**' + - 'dependencymanager/**' # Cancel superseded runs for the same branch. github.head_ref is only set for # pull_request events, so pushes fall back to github.ref, which groups per branch: @@ -118,6 +120,8 @@ jobs: - 'log.extension/**' examples: - 'examples/**' + dependencymanager: + - 'dependencymanager/**' - name: Felix Configuration JSON if: steps.changes.outputs.cm-json == 'true' || steps.changes.outputs.configurator == 'true' run: mvn -B -V -Dstyle.color=always --file cm.json/pom.xml clean install @@ -133,7 +137,7 @@ jobs: # code being changed rather than the last release. A producer is therefore built and # installed whenever it or one of its consumers changed. See FELIX-6870. - name: Resolve the versions built in this repository - if: steps.changes.outputs.framework == 'true' || steps.changes.outputs.http == 'true' || steps.changes.outputs.configadmin == 'true' || steps.changes.outputs.scr == 'true' || steps.changes.outputs.gogo == 'true' || steps.changes.outputs.utils == 'true' || steps.changes.outputs.resolver == 'true' + if: steps.changes.outputs.framework == 'true' || steps.changes.outputs.http == 'true' || steps.changes.outputs.configadmin == 'true' || steps.changes.outputs.scr == 'true' || steps.changes.outputs.gogo == 'true' || steps.changes.outputs.utils == 'true' || steps.changes.outputs.resolver == 'true' || steps.changes.outputs.dependencymanager == 'true' run: | record() { echo "$1=$2" >> "$GITHUB_ENV" @@ -147,10 +151,10 @@ jobs: record "GOGO_$(echo "$module" | tr 'a-z' 'A-Z')_VERSION" "$(mvn -B -q --file gogo/pom.xml -pl "$module" help:evaluate -Dexpression=project.version -DforceStdout)" done - name: Felix Framework - if: steps.changes.outputs.framework == 'true' || steps.changes.outputs.http == 'true' || steps.changes.outputs.configadmin == 'true' || steps.changes.outputs.scr == 'true' || steps.changes.outputs.gogo == 'true' + if: steps.changes.outputs.framework == 'true' || steps.changes.outputs.http == 'true' || steps.changes.outputs.configadmin == 'true' || steps.changes.outputs.scr == 'true' || steps.changes.outputs.gogo == 'true' || steps.changes.outputs.dependencymanager == 'true' run: mvn -B -V -Dstyle.color=always --file framework/pom.xml clean install - name: Felix Config Admin - if: steps.changes.outputs.configadmin == 'true' || steps.changes.outputs.scr == 'true' + if: steps.changes.outputs.configadmin == 'true' || steps.changes.outputs.scr == 'true' || steps.changes.outputs.dependencymanager == 'true' run: mvn -B -V -Dstyle.color=always --file configadmin/pom.xml clean install "-Dfelix.framework.version=$FRAMEWORK_VERSION" - name: Felix SCR if: steps.changes.outputs.scr == 'true' @@ -174,8 +178,8 @@ jobs: if: steps.changes.outputs.main == 'true' run: mvn -B -V -Dstyle.color=always --file main/pom.xml clean verify - name: Felix Gogo Shell - if: steps.changes.outputs.gogo == 'true' - run: mvn -B -V -Dstyle.color=always --file gogo/pom.xml clean verify "-Dfelix.gogo.command.version=$GOGO_COMMAND_VERSION" "-Dfelix.gogo.runtime.version=$GOGO_RUNTIME_VERSION" "-Dfelix.gogo.shell.version=$GOGO_SHELL_VERSION" "-Dfelix.gogo.jline.version=$GOGO_JLINE_VERSION" "-Dfelix.framework.version=$FRAMEWORK_VERSION" + if: steps.changes.outputs.gogo == 'true' || steps.changes.outputs.dependencymanager == 'true' + run: mvn -B -V -Dstyle.color=always --file gogo/pom.xml clean install "-Dfelix.gogo.command.version=$GOGO_COMMAND_VERSION" "-Dfelix.gogo.runtime.version=$GOGO_RUNTIME_VERSION" "-Dfelix.gogo.shell.version=$GOGO_SHELL_VERSION" "-Dfelix.gogo.jline.version=$GOGO_JLINE_VERSION" "-Dfelix.framework.version=$FRAMEWORK_VERSION" - name: Felix utils if: steps.changes.outputs.utils == 'true' || steps.changes.outputs.resolver == 'true' run: mvn -B -V -Dstyle.color=always --file utils/pom.xml clean install @@ -194,6 +198,17 @@ jobs: - name: Felix examples if: steps.changes.outputs.examples == 'true' run: mvn -B -V -Dstyle.color=always --file examples/pom.xml clean verify + # The Dependency Manager is built with Gradle and bnd rather than Maven. It runs last, + # on the framework, Gogo and Config Admin snapshots installed into the local Maven + # repository by the steps above. + - name: Felix Dependency Manager + if: steps.changes.outputs.dependencymanager == 'true' + working-directory: dependencymanager + run: | + # The annotation bundle is a bnd plugin used by the other projects. It has to exist + # before they are configured, so it is built in a separate Gradle invocation. + ./gradlew --no-daemon --console=plain org.apache.felix.dependencymanager.annotation:jar + ./gradlew --no-daemon --console=plain build - name: Upload Test Results if: always() uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 From 7d021d6a6281fec20b9b38230c952c17f5ba1383 Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 24 Oct 2026 19:57:51 +0000 Subject: [PATCH 5/8] FELIX-6872 - Dependency Manager: fix a race in FELIX5200_FactoryPidNotRestartedTest 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 Claude-Session: https://claude.ai/code/session_017MGDWAYvWioowRTBkoQPjA --- .../dm/itest/api/FELIX5200_FactoryPidNotRestartedTest.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dependencymanager/org.apache.felix.dependencymanager.itest/src/org/apache/felix/dm/itest/api/FELIX5200_FactoryPidNotRestartedTest.java b/dependencymanager/org.apache.felix.dependencymanager.itest/src/org/apache/felix/dm/itest/api/FELIX5200_FactoryPidNotRestartedTest.java index 1bab665482..0151ff9611 100644 --- a/dependencymanager/org.apache.felix.dependencymanager.itest/src/org/apache/felix/dm/itest/api/FELIX5200_FactoryPidNotRestartedTest.java +++ b/dependencymanager/org.apache.felix.dependencymanager.itest/src/org/apache/felix/dm/itest/api/FELIX5200_FactoryPidNotRestartedTest.java @@ -94,8 +94,9 @@ void updated(Dictionary properties) { } void start() { - m_ensure.steps(m_steps); + // the instance has to be published before the test thread is released by the step m_currentInstance = this; + m_ensure.steps(m_steps); } void stop() { From 99e1df58b6da9459b9e592ae7a81393af90b522c Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 24 Oct 2026 21:42:14 +0000 Subject: [PATCH 6/8] FELIX-6872 - Dependency Manager: make FELIX5200_FactoryPidNotRestartedTest 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 Claude-Session: https://claude.ai/code/session_017MGDWAYvWioowRTBkoQPjA --- .../FELIX5200_FactoryPidNotRestartedTest.java | 64 +++++++++++-------- 1 file changed, 37 insertions(+), 27 deletions(-) diff --git a/dependencymanager/org.apache.felix.dependencymanager.itest/src/org/apache/felix/dm/itest/api/FELIX5200_FactoryPidNotRestartedTest.java b/dependencymanager/org.apache.felix.dependencymanager.itest/src/org/apache/felix/dm/itest/api/FELIX5200_FactoryPidNotRestartedTest.java index 0151ff9611..9b484f09d9 100644 --- a/dependencymanager/org.apache.felix.dependencymanager.itest/src/org/apache/felix/dm/itest/api/FELIX5200_FactoryPidNotRestartedTest.java +++ b/dependencymanager/org.apache.felix.dependencymanager.itest/src/org/apache/felix/dm/itest/api/FELIX5200_FactoryPidNotRestartedTest.java @@ -21,10 +21,10 @@ import java.io.IOException; import java.util.Dictionary; import java.util.Properties; +import java.util.function.BooleanSupplier; import org.apache.felix.dm.Component; import org.apache.felix.dm.DependencyManager; -import org.apache.felix.dm.itest.util.Ensure; import org.apache.felix.dm.itest.util.TestBase; import org.junit.Assert; import org.osgi.service.cm.Configuration; @@ -35,24 +35,22 @@ * The factory configuration is created, the "Required" service is registered, so a factory configuration adapter INSTANCE1 is then created. * Now the "Required" service is unregistered: the factory config adapter INSTANCE1 is then stopped. * And when the "Required" service comes up again, then a new factory config adapter INSTANCE2 should be re-created, updated and started. + * When the factory configuration is removed, the factory config adapter instance is stopped. + *

+ * Config Admin may deliver the configuration to the factory more than once (for example when the factory is + * registered again), which makes the adapter instance be replaced by an other one. The test does not depend on + * how often that happens: it follows the instances instead of counting the calls. * * @author Felix Project Team */ public class FELIX5200_FactoryPidNotRestartedTest extends TestBase { - static FactoryPidComponent m_currentInstance; + private static final int TIMEOUT = 10000; - static Ensure m_ensure = new Ensure(); + // the instances of the adapter, in the order they have been started + static final java.util.List m_instances = new java.util.concurrent.CopyOnWriteArrayList<>(); - static Ensure.Steps m_steps = new Ensure.Steps( - 1, // updated is called the first time the adapter instance is created - 2, // component started - 3, // "Required" service is unregistered, and adapter instance is stopped - 4, // "Required" service is re-registered, a new adapter instance is created and called in updated - 5, // the new adapter instance is then started - 6 // the configuration is removed and the new adapter instance is stopped - ); - - public void testFactoryAdapterNotRestartedTest() { + public void testFactoryAdapterNotRestartedTest() throws InterruptedException { + m_instances.clear(); DependencyManager dm = getDM(); Component adapter = dm.createFactoryConfigurationAdapterService("factory.pid", "updated", false) @@ -71,36 +69,48 @@ public void testFactoryAdapterNotRestartedTest() { dm.add(adapter); dm.add(required); // adapter instance1 updated and started - m_ensure.waitForStep(2, 5000); - FactoryPidComponent currentInstance = m_currentInstance; + waitFor("the first adapter instance is started", () -> !m_instances.isEmpty()); + FactoryPidComponent instance1 = m_instances.get(0); + dm.remove(required); // adapter instance1 stopped - m_ensure.waitForStep(3, 5000); + waitFor("the first adapter instance is stopped", () -> instance1.m_stopped); + int started = m_instances.size(); + dm.add(required); - // adapter instance2 updated and started - m_ensure.waitForStep(5, 5000); - // a new adapter instance should have been created - Assert.assertNotEquals(currentInstance, m_currentInstance); + // a new adapter instance is created, updated and started + waitFor("a new adapter instance is started", () -> m_instances.size() > started); + FactoryPidComponent instance2 = m_instances.get(m_instances.size() - 1); + Assert.assertNotSame(instance1, instance2); + dm.remove(configurator); - // adapter instance2 stopped - m_ensure.waitForStep(6, 5000); + // the configuration is removed: the last adapter instance is stopped + waitFor("the adapter instance is stopped when the configuration is removed", () -> instance2.m_stopped); + } + + private void waitFor(String what, BooleanSupplier condition) throws InterruptedException { + long end = System.currentTimeMillis() + TIMEOUT; + while (!condition.getAsBoolean()) { + if (System.currentTimeMillis() > end) { + Assert.fail("Timed out waiting until " + what); + } + Thread.sleep(10); + } } public static class FactoryPidComponent { RequiredService m_required; + volatile boolean m_stopped; void updated(Dictionary properties) { - m_ensure.steps(m_steps); } void start() { - // the instance has to be published before the test thread is released by the step - m_currentInstance = this; - m_ensure.steps(m_steps); + m_instances.add(this); } void stop() { - m_ensure.steps(m_steps); + m_stopped = true; } } From 8c15f26ea2f42bde93b49f7679877f71335ee94a Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 25 Oct 2026 16:04:24 +0000 Subject: [PATCH 7/8] FELIX-6872 - Dependency Manager: ignore repeated deliveries of the same 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 Claude-Session: https://claude.ai/code/session_017MGDWAYvWioowRTBkoQPjA --- .../api/ConfigurationDependencyTest.java | 20 ++++++ ...8_TypeSafeConfigWithDefaultMethodTest.java | 10 +++ .../OptionalConfigurationDependencyTest.java | 5 ++ .../felix/dm/itest/util/ConfigDeliveries.java | 61 +++++++++++++++++++ 4 files changed, 96 insertions(+) create mode 100644 dependencymanager/org.apache.felix.dependencymanager.itest/src/org/apache/felix/dm/itest/util/ConfigDeliveries.java diff --git a/dependencymanager/org.apache.felix.dependencymanager.itest/src/org/apache/felix/dm/itest/api/ConfigurationDependencyTest.java b/dependencymanager/org.apache.felix.dependencymanager.itest/src/org/apache/felix/dm/itest/api/ConfigurationDependencyTest.java index 1303851340..e90581e0bb 100644 --- a/dependencymanager/org.apache.felix.dependencymanager.itest/src/org/apache/felix/dm/itest/api/ConfigurationDependencyTest.java +++ b/dependencymanager/org.apache.felix.dependencymanager.itest/src/org/apache/felix/dm/itest/api/ConfigurationDependencyTest.java @@ -27,6 +27,7 @@ import org.apache.felix.dm.Component; import org.apache.felix.dm.DependencyManager; +import org.apache.felix.dm.itest.util.ConfigDeliveries; import org.apache.felix.dm.itest.util.Ensure; import org.apache.felix.dm.itest.util.TestBase; import org.osgi.service.cm.Configuration; @@ -223,6 +224,7 @@ public void destroy() throws IOException { static class ConfigurationConsumer implements ManagedService, Runnable { protected final Ensure m_ensure; + protected final ConfigDeliveries m_deliveries = new ConfigDeliveries(); public ConfigurationConsumer(Ensure e) { m_ensure = e; @@ -230,6 +232,9 @@ public ConfigurationConsumer(Ensure e) { public void updated(Dictionary props) throws ConfigurationException { Assert.assertNotNull(props); + if (m_deliveries.isRepeat(props)) { + return; + } m_ensure.step(2); if (!"testvalue".equals(props.get("testkey"))) { Assert.fail("Could not find the configured property."); @@ -254,6 +259,9 @@ public ConfigurationConsumer3(Ensure e) { public void updated(Dictionary props) throws ConfigurationException { Assert.assertNotNull(props); + if (m_deliveries.isRepeat(props)) { + return; + } if (!"testvalue".equals(props.get("testkey"))) { Assert.fail("Could not find the configured property."); } @@ -277,6 +285,9 @@ public ConfigurationConsumer4(Ensure e) { } public void updated(Dictionary props) throws ConfigurationException { + if (m_deliveries.isRepeat(props)) { + return; + } if (! m_configured) { Assert.assertNotNull(props); if (!"testvalue".equals(props.get("testkey"))) { @@ -311,6 +322,7 @@ public void updatedWithComponentArg(Component component, Dictionary props) throw static class ConfigurationConsumerCallbackInstance { private final Ensure m_ensure; + private final ConfigDeliveries m_deliveries = new ConfigDeliveries(); public ConfigurationConsumerCallbackInstance(Ensure e) { m_ensure = e; @@ -318,6 +330,9 @@ public ConfigurationConsumerCallbackInstance(Ensure e) { public void updateConfiguration(Dictionary props) throws Exception { Assert.assertNotNull(props); + if (m_deliveries.isRepeat(props)) { + return; + } m_ensure.step(2); if (!"testvalue".equals(props.get("testkey"))) { Assert.fail("Could not find the configured property."); @@ -369,6 +384,7 @@ static interface MyConfig { static class ConfigurationConsumerWithTypeSafeConfiguration { private final Ensure m_ensure; + private final ConfigDeliveries m_deliveries = new ConfigDeliveries(); public ConfigurationConsumerWithTypeSafeConfiguration(Ensure e) { m_ensure = e; @@ -377,6 +393,9 @@ public ConfigurationConsumerWithTypeSafeConfiguration(Ensure e) { // configuration updates is always the first invoked callback (before init). public void updated(Component component, MyConfig cfg) throws ConfigurationException { if (cfg != null) { + if (m_deliveries.isRepeat((Object) cfg.getTestkey())) { + return; + } Assert.assertNotNull(component); Assert.assertNotNull(cfg); m_ensure.step(2); @@ -384,6 +403,7 @@ public void updated(Component component, MyConfig cfg) throws ConfigurationExcep Assert.fail("Could not find the configured property."); } } else { + m_deliveries.isRepeat((Dictionary) null); m_ensure.step(); } } diff --git a/dependencymanager/org.apache.felix.dependencymanager.itest/src/org/apache/felix/dm/itest/api/FELIX5238_TypeSafeConfigWithDefaultMethodTest.java b/dependencymanager/org.apache.felix.dependencymanager.itest/src/org/apache/felix/dm/itest/api/FELIX5238_TypeSafeConfigWithDefaultMethodTest.java index fe05d9b344..0096e073b9 100644 --- a/dependencymanager/org.apache.felix.dependencymanager.itest/src/org/apache/felix/dm/itest/api/FELIX5238_TypeSafeConfigWithDefaultMethodTest.java +++ b/dependencymanager/org.apache.felix.dependencymanager.itest/src/org/apache/felix/dm/itest/api/FELIX5238_TypeSafeConfigWithDefaultMethodTest.java @@ -20,6 +20,7 @@ import org.apache.felix.dm.Component; import org.apache.felix.dm.DependencyManager; +import org.apache.felix.dm.itest.util.ConfigDeliveries; import org.apache.felix.dm.itest.util.Ensure; import org.apache.felix.dm.itest.util.TestBase; import org.junit.Assert; @@ -93,6 +94,7 @@ public static interface MyConfigInterface { static class ConfigurationConsumerBase { protected final Ensure m_ensure; + protected final ConfigDeliveries m_deliveries = new ConfigDeliveries(); public ConfigurationConsumerBase(Ensure e) { m_ensure = e; @@ -116,6 +118,9 @@ public ConfigurationConsumer1(Ensure e) { // configuration updates is always the first invoked callback (before init). public void updated(Component component, MyConfigAnnot cfg) throws ConfigurationException { if (cfg != null) { + if (m_deliveries.isRepeat((Object) (cfg.getTestkey() + "/" + cfg.getTestkey2()))) { + return; + } Assert.assertNotNull(component); Assert.assertNotNull(cfg); if (!"testvalue".equals(cfg.getTestkey())) { @@ -126,6 +131,7 @@ public void updated(Component component, MyConfigAnnot cfg) throws Configuration } m_ensure.step(2); } else { + m_deliveries.isRepeat((java.util.Dictionary) null); m_ensure.step(); } } @@ -139,6 +145,9 @@ public ConfigurationConsumer2(Ensure e) { // configuration updates is always the first invoked callback (before init). public void updated(Component component, MyConfigInterface cfg) throws ConfigurationException { if (cfg != null) { + if (m_deliveries.isRepeat((Object) (cfg.getTestkey() + "/" + cfg.getTestkey2()))) { + return; + } Assert.assertNotNull(component); Assert.assertNotNull(cfg); if (!"testvalue".equals(cfg.getTestkey())) { @@ -149,6 +158,7 @@ public void updated(Component component, MyConfigInterface cfg) throws Configura } m_ensure.step(2); } else { + m_deliveries.isRepeat((java.util.Dictionary) null); m_ensure.step(); } } diff --git a/dependencymanager/org.apache.felix.dependencymanager.itest/src/org/apache/felix/dm/itest/api/OptionalConfigurationDependencyTest.java b/dependencymanager/org.apache.felix.dependencymanager.itest/src/org/apache/felix/dm/itest/api/OptionalConfigurationDependencyTest.java index cc8c834cc7..49c3dcec22 100644 --- a/dependencymanager/org.apache.felix.dependencymanager.itest/src/org/apache/felix/dm/itest/api/OptionalConfigurationDependencyTest.java +++ b/dependencymanager/org.apache.felix.dependencymanager.itest/src/org/apache/felix/dm/itest/api/OptionalConfigurationDependencyTest.java @@ -20,6 +20,7 @@ import org.apache.felix.dm.Component; import org.apache.felix.dm.DependencyManager; +import org.apache.felix.dm.itest.util.ConfigDeliveries; import org.apache.felix.dm.itest.util.Ensure; import org.apache.felix.dm.itest.util.TestBase; import org.junit.Assert; @@ -70,6 +71,7 @@ public static interface MyConfig { static class OptionalConfigurationConsumer { protected final Ensure m_ensure; protected volatile int m_updateCount; + private final ConfigDeliveries m_deliveries = new ConfigDeliveries(); public OptionalConfigurationConsumer(Ensure e) { m_ensure = e; @@ -77,6 +79,9 @@ public OptionalConfigurationConsumer(Ensure e) { public void updated(MyConfig cnf) { // optional configuration, called after start(), like any other optional dependency callbacks. if (cnf != null) { + if (m_deliveries.isRepeat((Object) cnf.getTestkey())) { + return; // the same configuration delivered again + } m_updateCount ++; if (m_updateCount == 1) { if (!"default".equals(cnf.getTestkey())) { diff --git a/dependencymanager/org.apache.felix.dependencymanager.itest/src/org/apache/felix/dm/itest/util/ConfigDeliveries.java b/dependencymanager/org.apache.felix.dependencymanager.itest/src/org/apache/felix/dm/itest/util/ConfigDeliveries.java new file mode 100644 index 0000000000..8250ef8093 --- /dev/null +++ b/dependencymanager/org.apache.felix.dependencymanager.itest/src/org/apache/felix/dm/itest/util/ConfigDeliveries.java @@ -0,0 +1,61 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.felix.dm.itest.util; + +import java.util.Collections; +import java.util.Dictionary; +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; + +/** + * Detects that Config Admin delivers the same configuration again to a callback. + *

+ * Config Admin can provide a configuration to a service twice, for example once because the service registers + * while the configuration is updated (an update of the registration and an update of the configuration, close + * together). The tests count the configuration updates they expect, and ignore such a repeated delivery. + */ +public class ConfigDeliveries { + private Object m_last; + + /** + * @return true if the configuration is the one which has been delivered the last time. A lost configuration + * (null) is never a repeat. + */ + public synchronized boolean isRepeat(Dictionary properties) { + if (properties == null) { + m_last = null; + return false; + } + Map copy = new HashMap<>(); + for (Object key : Collections.list(properties.keys())) { + copy.put(key, properties.get(key)); + } + return isRepeat((Object) copy); + } + + /** + * @param identity describes the content of a typed configuration, for example the values of its properties. + */ + public synchronized boolean isRepeat(Object identity) { + boolean repeat = identity != null && Objects.equals(identity, m_last); + m_last = identity; + return repeat; + } +} From 440f06177cfb9979fac2f11c687c2837ab882bd6 Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 25 Oct 2026 18:12:20 +0000 Subject: [PATCH 8/8] FELIX-6872 - Dependency Manager: ignore the harmless Config Admin message 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 Claude-Session: https://claude.ai/code/session_017MGDWAYvWioowRTBkoQPjA --- .../felix/dm/index/itest/tests/TestBase.java | 19 ++++++++++++++----- .../apache/felix/dm/itest/util/TestBase.java | 19 ++++++++++++++----- .../felix/dm/lambda/itest/TestBase.java | 19 ++++++++++++++----- 3 files changed, 42 insertions(+), 15 deletions(-) diff --git a/dependencymanager/org.apache.felix.dependencymanager.index.itest/src/org/apache/felix/dm/index/itest/tests/TestBase.java b/dependencymanager/org.apache.felix.dependencymanager.index.itest/src/org/apache/felix/dm/index/itest/tests/TestBase.java index edda18832d..fa17ba1272 100644 --- a/dependencymanager/org.apache.felix.dependencymanager.index.itest/src/org/apache/felix/dm/index/itest/tests/TestBase.java +++ b/dependencymanager/org.apache.felix.dependencymanager.index.itest/src/org/apache/felix/dm/index/itest/tests/TestBase.java @@ -249,14 +249,14 @@ public L getLogger(Class clazz, Class } public void log(int level, String message) { - checkError(level, null); + checkError(level, message, null); if (LOG_LEVEL >= level) { System.out.println(getLevel(level) + " - " + Thread.currentThread().getName() + " : " + message); } } public void log(int level, String message, Throwable exception) { - checkError(level, exception); + checkError(level, message, exception); if (LOG_LEVEL >= level) { StringBuilder sb = new StringBuilder(); sb.append(getLevel(level) + " - " + Thread.currentThread().getName() + " : "); @@ -267,7 +267,7 @@ public void log(int level, String message, Throwable exception) { } public void log(ServiceReference sr, int level, String message) { - checkError(level, null); + checkError(level, message, null); if (LOG_LEVEL >= level) { StringBuilder sb = new StringBuilder(); sb.append(getLevel(level) + " - " + Thread.currentThread().getName() + " : "); @@ -277,7 +277,7 @@ public void log(ServiceReference sr, int level, String message) { } public void log(ServiceReference sr, int level, String message, Throwable exception) { - checkError(level, exception); + checkError(level, message, exception); if (LOG_LEVEL >= level) { StringBuilder sb = new StringBuilder(); sb.append(getLevel(level) + " - " + Thread.currentThread().getName() + " : "); @@ -317,7 +317,16 @@ private String getLevel(int level) { } } - private void checkError(int level, Throwable exception) { + // Config Admin logs this 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, so it is not an error. + private static boolean isIgnoredMessage(String message) { + return message != null && message.startsWith("Ignoring new configuration pid="); + } + + private void checkError(int level, String message, Throwable exception) { + if (isIgnoredMessage(message) && exception == null) { + return; + } if (level <= LOG_ERROR) { m_errorsLogged = true; } diff --git a/dependencymanager/org.apache.felix.dependencymanager.itest/src/org/apache/felix/dm/itest/util/TestBase.java b/dependencymanager/org.apache.felix.dependencymanager.itest/src/org/apache/felix/dm/itest/util/TestBase.java index 6873f9c98d..c1754cd58c 100644 --- a/dependencymanager/org.apache.felix.dependencymanager.itest/src/org/apache/felix/dm/itest/util/TestBase.java +++ b/dependencymanager/org.apache.felix.dependencymanager.itest/src/org/apache/felix/dm/itest/util/TestBase.java @@ -248,14 +248,14 @@ public L getLogger(Class clazz, Class } public void log(int level, String message) { - checkError(level, null); + checkError(level, message, null); if (LOG_LEVEL >= level) { System.out.println(getLevel(level) + " - " + Thread.currentThread().getName() + " : " + message); } } public void log(int level, String message, Throwable exception) { - checkError(level, exception); + checkError(level, message, exception); if (LOG_LEVEL >= level) { StringBuilder sb = new StringBuilder(); sb.append(getLevel(level) + " - " + Thread.currentThread().getName() + " : "); @@ -266,7 +266,7 @@ public void log(int level, String message, Throwable exception) { } public void log(ServiceReference sr, int level, String message) { - checkError(level, null); + checkError(level, message, null); if (LOG_LEVEL >= level) { StringBuilder sb = new StringBuilder(); sb.append(getLevel(level) + " - " + Thread.currentThread().getName() + " : "); @@ -276,7 +276,7 @@ public void log(ServiceReference sr, int level, String message) { } public void log(ServiceReference sr, int level, String message, Throwable exception) { - checkError(level, exception); + checkError(level, message, exception); if (LOG_LEVEL >= level) { StringBuilder sb = new StringBuilder(); sb.append(getLevel(level) + " - " + Thread.currentThread().getName() + " : "); @@ -316,7 +316,16 @@ private String getLevel(int level) { } } - private void checkError(int level, Throwable exception) { + // Config Admin logs this 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, so it is not an error. + private static boolean isIgnoredMessage(String message) { + return message != null && message.startsWith("Ignoring new configuration pid="); + } + + private void checkError(int level, String message, Throwable exception) { + if (isIgnoredMessage(message) && exception == null) { + return; + } if (level <= LOG_ERROR) { m_errorsLogged = true; } diff --git a/dependencymanager/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/lambda/itest/TestBase.java b/dependencymanager/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/lambda/itest/TestBase.java index 2cbc24dba9..8df2dd0e13 100644 --- a/dependencymanager/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/lambda/itest/TestBase.java +++ b/dependencymanager/org.apache.felix.dependencymanager.lambda.itest/src/org/apache/felix/dm/lambda/itest/TestBase.java @@ -242,14 +242,14 @@ public L getLogger(Class clazz, Class } public void log(int level, String message) { - checkError(level, null); + checkError(level, message, null); if (LOG_LEVEL >= level) { System.out.println(getLevel(level) + " - " + Thread.currentThread().getName() + " : " + message); } } public void log(int level, String message, Throwable exception) { - checkError(level, exception); + checkError(level, message, exception); if (LOG_LEVEL >= level) { StringBuilder sb = new StringBuilder(); sb.append(getLevel(level) + " - " + Thread.currentThread().getName() + " : "); @@ -261,7 +261,7 @@ public void log(int level, String message, Throwable exception) { @SuppressWarnings("rawtypes") public void log(ServiceReference sr, int level, String message) { - checkError(level, null); + checkError(level, message, null); if (LOG_LEVEL >= level) { StringBuilder sb = new StringBuilder(); sb.append(getLevel(level) + " - " + Thread.currentThread().getName() + " : "); @@ -272,7 +272,7 @@ public void log(ServiceReference sr, int level, String message) { @SuppressWarnings("rawtypes") public void log(ServiceReference sr, int level, String message, Throwable exception) { - checkError(level, exception); + checkError(level, message, exception); if (LOG_LEVEL >= level) { StringBuilder sb = new StringBuilder(); sb.append(getLevel(level) + " - " + Thread.currentThread().getName() + " : "); @@ -312,7 +312,16 @@ private String getLevel(int level) { } } - private void checkError(int level, Throwable exception) { + // Config Admin logs this 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, so it is not an error. + private static boolean isIgnoredMessage(String message) { + return message != null && message.startsWith("Ignoring new configuration pid="); + } + + private void checkError(int level, String message, Throwable exception) { + if (isIgnoredMessage(message) && exception == null) { + return; + } if (level <= LOG_ERROR) { m_errorsLogged = true; }