Roy Teeuwen created SLING-13197:
-----------------------------------
Summary: Feature Model: detect Bundle-SymbolicName collisions
during assembly
Key: SLING-13197
URL: https://issues.apache.org/jira/browse/SLING-13197
Project: Sling
Issue Type: Improvement
Components: Feature Model
Affects Versions: Feature Model 2.0.4
Reporter: Roy Teeuwen
*Context*
FeatureBuilder.assemble() deduplicates conflicting bundles by Maven
groupId:artifactId via BuilderContext.addArtifactsOverride(). This is fine when
the feature file is created through declarations in a pom.xml / maven.
It stops working when cpconverter is used on a content package and the included
bundle was not produced by maven and thus doesn't contain an embedded META-INF/
pom properties. The cpconverter then falls back to deriving coordinates from
the OSGi Bundle-SymbolicName.
Concrete examples I'm hitting this are for example in the aem-groovy-console
where i'm trying to set up integration tests for it, using the sling starter 14
feature model and adding the groovy console as extra feature file by first
converting it to a feature file:
- Sling Starter 14 feature model ships org.ow2.asm:asm-tree:9.9.1. The same
jar embedded into a content package and run through cpconverter becomes
org.objectweb.asm:tree:9.9.1. Different Maven GAVs, identical OSGi
BSN+Bundle-Version. assemble() lets both through, then Felix at install time
refuses with Bundle symbolic name and version are not unique:
org.objectweb.asm.tree:9.9.1.
- Sling Starter 14 feature model ships org.apache.groovy:groovy-xml:4.0.10.
The same family of artifacts embedded at version 5.0.5 and run through
cpconverter becomes groovy-xml:groovy-xml:5.0.5
*Proposed change*
A new opt-in toggle on BuilderContext that enables BSN-collision detection
during assemble().
Behaviour when setOsgiBsnCollisionDetection(true) has been called (no-op
otherwise — full backward compatibility):
After FeatureBuilder.assemble() finishes the existing GAV-merge, a new pass
groups the assembled bundles by Bundle-SymbolicName (read from each JAR's
manifest). For any group of size ≥ 2 the wildcard {*}:{*}:<rule> entries in
BuilderContext.getArtifactOverrides() are consulted:
- HIGHEST → keep the bundle with the highest Bundle-Version
- LATEST → keep the last bundle in iteration order
- FIRST → keep the first
- ALL → keep all (effectively disable for this group)
- A literal version → keep the bundle whose Bundle-Version matches it
*Backward compatibility*
Currently I'm going for default osgiBsnCollisionDetection is false →
BSN-comparison is skipped → existing assemblies behave identically.
An alternative would be implicit opt-in: detection runs whenever any wildcard
{*}:{*}:<rule> override is configured, with no separate toggle.
- Pro: zero new API surface; the change is invisible to anyone not using
wildcard overrides.
- Con: a user who adds {*}:{*}:HIGHEST for normal Maven-GAV clashes would get
BSN-collision detection as an unrelated side effect they may not have asked for.
Will currently go for opt-in, unless everyone is happy with making this the
default
--
This message was sent by Atlassian Jira
(v8.20.10#820010)