Skip to content

Commit 6144325

Browse files
committed
do not concat BUNDLE_ACTIVATOR
fixes a problem in Verifier.verifyActivator() ("The Bundle-Activator header only supports a single type. The following types were found") when the bnd instructions already define a Bundle-Activator but a processed jar also contributed a Bundle-Activator. Before this fix the Bundle-Activator header was concatenated to the existing Bundle-Activator header in bnd.bnd and thus contained multiple values (separated by comma). But for Bundle-Activator this does not make sense as it supports only a single value. Added Constants.BUNDLE_HEADERS_SINGLE_VALUE for a list of other headers which should also not be concatenated Signed-off-by: Christoph Rueger <[email protected]>
1 parent 7411173 commit 6144325

File tree

2 files changed

+98
-1
lines changed

2 files changed

+98
-1
lines changed

biz.aQute.bndlib.tests/test/test/BuilderTest.java

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3091,6 +3091,86 @@ public void testFindActivator() throws Exception {
30913091
}
30923092
}
30933093

3094+
/**
3095+
* Check that the defined activator is found, and not concatenated by the
3096+
* Bundle-Activator annotation in TypeInVersionedPackage
3097+
*
3098+
* @throws Exception
3099+
*/
3100+
@Test
3101+
public void testBundleActivatorShouldNotBeConcatenated() throws Exception {
3102+
Builder bmaker = new Builder();
3103+
try {
3104+
bmaker.setProperty("Bundle-Activator", "test.activator.Activator");
3105+
bmaker.setProperty("build", "xyz"); // for @Version annotation
3106+
bmaker.setProperty("Private-Package", "test.*");
3107+
bmaker.setProperty("-bundleannotations",
3108+
"test.annotationheaders.attrs.std.activator.TypeInVersionedPackage");
3109+
// bmaker.setProperty("-dsannotations", "!*");
3110+
// bmaker.setProperty("-metatypeannotations", "!*");
3111+
bmaker.setClasspath(new File[] {
3112+
new File("bin_test")
3113+
});
3114+
bmaker.setProperty("-fixupmessages.export",
3115+
"The annotation aQute.bnd.annotation.Export applied to package test.versionpolicy.api is deprecated and will be removed in a future release. The org.osgi.annotation.bundle.Export should be used instead");
3116+
bmaker.setProperty("-fixupmessages.directive",
3117+
"Unknown directive foobar: in Export-Package, allowed directives are uses:,mandatory:,include:,exclude:,-import:, and 'x-*'");
3118+
3119+
Jar jar = bmaker.build();
3120+
report("testBundleActivatorShouldNotBeConcatenated", bmaker, jar);
3121+
3122+
Attributes main = jar.getManifest()
3123+
.getMainAttributes();
3124+
assertEquals("test.activator.Activator", main.getValue(Constants.BUNDLE_ACTIVATOR));
3125+
assertFalse(
3126+
bmaker
3127+
.check(
3128+
"The Bundle-Activator header only supports a single type. The following types were found: test.activator.Activator,test.annotationheaders.attrs.std.activator.TypeInVersionedPackage. This usually happens when a macro resolves to multiple types"));
3129+
} finally {
3130+
bmaker.close();
3131+
}
3132+
}
3133+
3134+
/**
3135+
* Check that the Bundle-Activator annotation in TypeInVersionedPackage
3136+
* defines the Bundle-Activator of our bundle.
3137+
*
3138+
* @throws Exception
3139+
*/
3140+
@Test
3141+
public void testBundleActivatorFromAnnotation() throws Exception {
3142+
Builder bmaker = new Builder();
3143+
try {
3144+
// bmaker.setProperty("Bundle-Activator",
3145+
// "test.activator.Activator");
3146+
bmaker.setProperty("build", "xyz"); // for @Version annotation
3147+
bmaker.setProperty("Private-Package", "test.*");
3148+
bmaker.setProperty("-bundleannotations",
3149+
"test.annotationheaders.attrs.std.activator.TypeInVersionedPackage,*");
3150+
bmaker.setClasspath(new File[] {
3151+
new File("bin_test")
3152+
});
3153+
bmaker.setProperty("-fixupmessages.export",
3154+
"The annotation aQute.bnd.annotation.Export applied to package test.versionpolicy.api is deprecated and will be removed in a future release. The org.osgi.annotation.bundle.Export should be used instead");
3155+
bmaker.setProperty("-fixupmessages.directive",
3156+
"Unknown directive foobar: in Export-Package, allowed directives are uses:,mandatory:,include:,exclude:,-import:, and 'x-*'");
3157+
3158+
Jar jar = bmaker.build();
3159+
// assertTrue(bmaker.check());
3160+
report("testBundleActivatorFromAnnotation", bmaker, jar);
3161+
3162+
Attributes main = jar.getManifest()
3163+
.getMainAttributes();
3164+
assertEquals("test.annotationheaders.attrs.std.activator.TypeInVersionedPackage",
3165+
main.getValue(Constants.BUNDLE_ACTIVATOR));
3166+
3167+
assertFalse(bmaker.check(
3168+
"The Bundle-Activator header only supports a single type*"));
3169+
} finally {
3170+
bmaker.close();
3171+
}
3172+
}
3173+
30943174
@Test
30953175
public void testImportVersionRange() throws Exception {
30963176
assertVersionEquals("[1.1,2.0)", "[1.1,2.0)");

biz.aQute.bndlib/src/aQute/bnd/osgi/AnnotationHeaders.java

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,14 @@ class AnnotationHeaders extends ClassDataCollector implements Closeable {
146146
PROVIDE_CAPABILITY, BUNDLE_CATEGORY, BUNDLE_DOC_URL, BUNDLE_DEVELOPERS, BUNDLE_CONTRIBUTORS, BUNDLE_COPYRIGHT,
147147
STD_REQUIREMENT, STD_CAPABILITY, STD_HEADER);
148148

149+
/**
150+
* OSGi Bundle headers, which only allow a single value (i.e. not multiple
151+
* values concatenated by comma)
152+
*/
153+
private static final Set<String> BUNDLE_HEADERS_SINGLE_VALUE = Sets.of(Constants.BUNDLE_ACTIVATOR,
154+
Constants.BUNDLE_ACTIVATIONPOLICY, Constants.BUNDLE_NAME, Constants.BUNDLE_SYMBOLICNAME,
155+
Constants.BUNDLE_VERSION, Constants.BUNDLE_MANIFESTVERSION, Constants.MAIN_CLASS);
156+
149157
// Used to detect attributes and directives on Require-Capability and
150158
// Provide-Capability
151159
static final String STD_ATTRIBUTE = "org.osgi.annotation.bundle.Attribute";
@@ -1030,11 +1038,20 @@ private void add(Annotation annotation, String name, String value) throws IOExce
10301038
/*
10311039
* This method is a pass thru for the properties of the analyzer. If we have
10321040
* such a header, we get the analyzer header and concatenate our values
1033-
* after removing dups.
1041+
* after removing dups. But there are exceptions: Some headers (e.g.
1042+
* Bundle-Activator) only allow a single value and for them concatenating to
1043+
* the analyzer header does not make sense.
10341044
*/
10351045

10361046
public String getHeader(String name) {
10371047
String value = analyzer.getProperty(name);
1048+
1049+
// for some OSGi headers we do not want to concatenate to existing
1050+
// analyzer value (analyzer value wins)
1051+
if (value != null && BUNDLE_HEADERS_SINGLE_VALUE.contains(name)) {
1052+
return value;
1053+
}
1054+
10381055
if (headers.containsKey(name)) {
10391056
//
10401057
// Remove duplicates and sort

0 commit comments

Comments
 (0)