From e959863f22f2fb68bb3a063f533e5f13479b7d37 Mon Sep 17 00:00:00 2001 From: Christoph Rueger Date: Thu, 3 Oct 2024 18:32:13 +0200 Subject: [PATCH] docs for -metainf-services Signed-off-by: Christoph Rueger --- .../bnd/osgi/metainf/MetaInfService.java | 1 - docs/_chapters/230-manifest-annotations.md | 8 ++++ docs/_instructions/metainf-services.md | 47 +++++++++++++++++++ 3 files changed, 55 insertions(+), 1 deletion(-) create mode 100644 docs/_instructions/metainf-services.md diff --git a/biz.aQute.bndlib/src/aQute/bnd/osgi/metainf/MetaInfService.java b/biz.aQute.bndlib/src/aQute/bnd/osgi/metainf/MetaInfService.java index c65670f84e..358b7f7927 100644 --- a/biz.aQute.bndlib/src/aQute/bnd/osgi/metainf/MetaInfService.java +++ b/biz.aQute.bndlib/src/aQute/bnd/osgi/metainf/MetaInfService.java @@ -228,7 +228,6 @@ public MetaInfService(String serviceName, String source) { // just comment continue; } - implementations.put(line, new Implementation(line, annotations, comments)); annotations.clear(); comments.clear(); diff --git a/docs/_chapters/230-manifest-annotations.md b/docs/_chapters/230-manifest-annotations.md index 14ddecde52..4e79cefafd 100644 --- a/docs/_chapters/230-manifest-annotations.md +++ b/docs/_chapters/230-manifest-annotations.md @@ -42,6 +42,8 @@ META-INF/services/com.example.ServiceType: ``` The processing is identical to the normal class based annotation processing. The `#class` macro will be set to the implementation class. The `#value` will be set in all cases to the service type unless overridden. +This behavior can be controlled with the [-metainf-services](/instructions/metainf-services.html) instruction. You can set `-metainf-services: auto` to also automatically create `Provide-Capability` headers for services without annotations. + Clearly using the class annotation is far superior: * Help from the IDE @@ -52,6 +54,12 @@ The analysis of these files happens after the analyzer plugins have been run. Th Since the annotations & imports happen in the comments, it is not possible to diagnose any errors. If the comment does not match its regular expression, it will be silently ignored. + +**Note:** Make sure `biz.aQute.bnd.annotation` is on the classpath / buildpath which contains the `aQute.bnd.annotation.spi.ServiceProvider` annotation. Otherwise the annotation won't be processed and you might see a warning in the log like this: + +`Unable to determine whether the meta annotation aQute.bnd.annotation.spi.ServiceProvider applied to type xyz provides bundle annotations as it is not on the project build path. If this annotation does provide bundle annotations then it must be present on the build path in order to be processed` + + ### @Requirement & @Capability Annotations Though Java class files contain enough information to find code dependencies, there are many dependencies that are indirect. OSGi _extenders_ for instance are often a requirement to make a bundle function correctly but often client bundles have no code dependency on the extender. For example, Declarative Services (DS) went out of its way to allow components to be Plain Old Java Objects (POJO). The result is that resolving a closure of bundles starting from a DS client bundle would not drag in the Service Component Runtime (SCR), resulting in a satisfied but rather idle closure. diff --git a/docs/_instructions/metainf-services.md b/docs/_instructions/metainf-services.md new file mode 100644 index 0000000000..b9562a7011 --- /dev/null +++ b/docs/_instructions/metainf-services.md @@ -0,0 +1,47 @@ +--- +layout: default +class: Analyzer +title: -metainf-services +summary: Controls how META-INF/services files are processed. +--- + +The `-metainf-services` instruction tells **bnd** how files in the `META-INF/services` should be processed. +See the chapter about [META-INF/services Annotations](/chapters/230-manifest-annotations.html#meta-infservices-annotations) how to apply Bundle annotations to the files in the `META-INF/services`. + +This instruction can have the following values: + +- `annotation` (default if not set): Scan files and only process annotations. +- `auto`: process annotations and special treatment and auto-register services without annotations. That means that bnd auto-generates a `aQute.bnd.annotation.spi.ServiceProvider` annotation without attributes if an Implementation doesn't have one. This is useful if you just want to have bnd generate the `Provide-Capability` headers for `osgi.serviceloader`. +- `none`: disable processing of files in `META-INF/services` + +## Example + +Assume we want to wrap a non-OSGi library. +Create `bnd.bnd` file and a library having a `META-INF/services` folder e.g. [groovy-3.0.22.jar](https://mvnrepository.com/artifact/org.codehaus.groovy/groovy/3.0.22) in a local `lib` folder. +We will use `-includeresource: @lib/groovy-3.0.22.jar` to [unroll the jar](/instructions/includeresource.html#rolling). + +``` +# bnd.bnd +-buildpath: biz.aQute.bnd.annotation;version='7.0' +-includeresource: @lib/groovy-3.0.22.jar +-metainf-services: auto +``` + +This creates a new jar with the following MANIFEST.MF headers from the `META-INF/services` folder: + +``` +# MANIFEST.MF +Provide-Capability osgi.service;objectClass:List="org.codehaus.groovy.transform.ASTTransformation";effective:=active + osgi.serviceloader;osgi.serviceloader="org.codehaus.groovy.transform.ASTTransformation";register:="groovy.grape.GrabAnnotationTransformation" +Require-Capability osgi.ee;filter:="(&(osgi.ee=JavaSE)(version=1.8))" + osgi.extender;filter:="(&(osgi.extender=osgi.serviceloader.registrar)(version>=1.0.0)(!(version>=2.0.0)))" +``` + +`-metainf-services: auto` causes bnd to process annotations and also auto-generate an annotation for services without annotations. +To prevent the latter (auto-generation) use the default `-metainf-services: annotation` or remove the instruction completely. + +**Note:** Make sure `biz.aQute.bnd.annotation` is on the classpath / buildpath which contains `aQute.bnd.annotation.spi.ServiceProvider` annotation. + + + +[source](https://github.com/bndtools/bnd/blob/master/biz.aQute.bndlib/src/aQute/bnd/osgi/metainf/MetaInfServiceParser.java) \ No newline at end of file