Fix FilterImpl.WrapperCapability: Filter.matches(Map) always throws - #554
Fix FilterImpl.WrapperCapability: Filter.matches(Map) always throws#554paulrutter wants to merge 3 commits into
Conversation
Two defects were introduced in 466eb93 ("[fw] reduce warning related to types Classes"), both in org.apache.felix.framework.FilterImpl.WrapperCapability. They were found by the OSGi Core R8 TCK, which reported 33 errors across BundleContextFilterTests and DivTests. 1. Filter.matches(Map) throws for any non-empty map. The constructor lost its assignment into a stray empty if block: m_map = Collections.emptyMap(); if(map != null ) { } m_map.putAll(map); m_map therefore refers to an immutable empty map and putAll throws UnsupportedOperationException, or NullPointerException when map is null. It previously read: m_map = (map == null) ? Collections.EMPTY_MAP : map; which is restored. Filter.matches(Map) has been unusable since April 2025. 2. WrapperCapability(ServiceReference) requires an OSGi Core 1.10 method. It was rewritten to read properties via new DictionaryToMap(sr.getProperties(), false). ServiceReference.getProperties() was only added in Core 1.10 and is not implemented by every ServiceReference; the TCK's own mock throws UnsupportedOperationException for it. Restored to the getPropertyKeys()/getProperty() loop, which every implementation supports. Adds regression tests for both. They exercise org.apache.felix.framework.FilterImpl directly, since FrameworkUtil.createFilter returns the unrelated org.osgi.framework.FilterImpl. Verified that both fail with UnsupportedOperationException against the current code and pass with the fix. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The OSGi Core TCK currently cannot resolve on any JDK, so framework.tck fails before executing a single test. That is what hid the FilterImpl defects fixed in this branch, and it also means CI cannot demonstrate the fix without repairing it. Two ranges were left behind when assertj-core was bumped from 3.27.3 to 3.27.7 in #478: - tck.bndrun still required assertj-core [3.27.3,3.27.4), so the bndrun could not be resolved at all: "assertj-core;version=[3.27.3,3.27.4) Not found in [... assertj-core;version=3.27.7 ...]". - assertj-core 3.27.7 imports net.bytebuddy [1.18.0,2.0.0) but byte-buddy was pinned at 1.17.5, so assertj-core then failed to start with an unresolved osgi.wiring.package requirement. Also removes a duplicate junit-platform-launcher dependency, which Maven reports as a malformed model and warns it may reject in future. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
Added the TCK dependency fixes to this branch, because the TCK cannot resolve on master at all and it is the thing that demonstrates the CI on the first push failed with: That is pre-existing master breakage, not fallout from this change. Two ranges were left behind when assertj-core was bumped 3.27.3 to 3.27.7 in #478:
Both are fixed here, along with a duplicate Scope note: #433 additionally moves the bnd plugins and With these in place the TCK should actually execute on this branch, which is what makes the |
The framework step ran clean verify, which does not install. The TCK is a separate Maven invocation, so it resolves org.apache.felix.framework from the repository rather than from the build that just ran, and org.apache.felix.framework 7.1.0-SNAPSHOT exists in apache.snapshots. Resolution therefore succeeded against the published snapshot and the TCK never exercised the code under test. That matters for this pull request in particular: the FilterImpl defects it fixes are exactly what the TCK reports, so a green TCK run proved nothing while the framework was being resolved from elsewhere. Running clean install makes the TCK test the framework this build produced. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
Added a CI fix, because the green TCK run on the previous commit did not actually validate anything in this PR. The workflow ran That matters most for this PR specifically: the This surfaced on #433, where renaming the framework to The step now runs For what it is worth, the fix was verified locally against the real thing: the TCK went from 33 errors, to 14 after repairing the |
org.apache.felix.framework.FilterImpl.WrapperCapabilityhas two defects, both introduced by 466eb93 "[fw] reduce warning related to types Classes" — a generics cleanup that changed behaviour by accident. They surfaced while running the OSGi Core R8 TCK for #433, which reported 33 errors acrossBundleContextFilterTestsandDivTests; both trace back here.1.
Filter.matches(Map)throws for any non-empty mapThe constructor lost its assignment into a stray empty
ifblock:m_maprefers to an immutable empty map, soputAllthrowsUnsupportedOperationExceptionfor any non-empty argument, andNullPointerExceptionfor a null one. It previously read:which is restored here.
Filter.matches(Map)has been unusable since April 2025, so this affects released versions independently of any Java version work.2.
WrapperCapability(ServiceReference)requires an OSGi Core 1.10 methodIt was rewritten to
new DictionaryToMap(sr.getProperties(), false).ServiceReference.getProperties()was only added in Core 1.10 and is not implemented by everyServiceReference— the TCK's own mock throwsUnsupportedOperationExceptionfor it. Restored to thegetPropertyKeys()/getProperty()loop, which every implementation supports.Tests
Adds regression tests for both cases. They construct
org.apache.felix.framework.FilterImpldirectly, becauseFrameworkUtil.createFilterreturns the unrelatedorg.osgi.framework.FilterImpland does not exercise this code at all — worth knowing, as it is an easy trap when testing this class.Verified both ways: the new tests fail with
UnsupportedOperationExceptionagainst current master and pass with the fix.@stbischof — flagging you as the author of 466eb93 so you can sanity-check the intent. The generics conversion itself looks right; it just seems the
m_map = mapassignment and the property loop were lost in the edit. Happy to adjust if you had something else in mind for either constructor.These are independent of the Java 25 work in #433, which is why they are proposed separately against
master; #433 carries the same fix so its TCK run can pass, and that will drop out when this merges.🤖 Generated with Claude Code