This plugin for Maven 2 is based on the BND tool from Peter Kriens. The way BND works is by treating your project as a big collection of classes (e.g., project code, dependencies, and the class path). The way you create a bundle with BND is to tell it the content of the bundle's JAR file as a subset of the available classes. This plugin wraps BND to make it work specifically with the Maven 2 project structure and to provide it with reasonable default behavior for Maven 2 projects.
Rather than going straight to a detailed list of plugin features, we will first look at a simple example of how to use the plugin to give an immediate flavor. A detailed "how to" will follow.
Assume that we have a simple bundle project that has a pubic API package an several implementation packages, such as:
org.foo.myproject.api org.foo.myproject.impl1 org.foo.myproject.impl2 ... |
If we also assume that we have a bundle activator in one of the implementation packages, then <plugins> section of the POM file would look like this:
...
<plugins>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>bundle-plugin</artifactId>
<extensions>true</extensions>
<configuration>
<instructions>
<Export-Package>org.foo.myproject.api</Export-Package>
<Private-Package>org.foo.myproject.*</Private-Package>
<Bundle-Activator>org.foo.myproject.impl1.Activator</Bundle-Activator>
</instructions>
</configuration>
</plugin>
<plugins>
...
|
The <Export-Package> and <Private-Package> instructions tell the plugin about the contents of the bundle JAR file. The <Export-Package> instruction tells the plugin which of the available packages to include into the bundle and to export, while the <Private-Package> instruction indicates which of the available packages to include into the bundle but not export. If the two sets overlap, as they do in the case, then the export takes precedence. Since we did not specify any values for any other bundle manifest headers, they will assume default values which are described below. One specific behavior to highlight is that the plugin generates the Import-Package bundle manifest header based on the specified contents of the bundle, which means that you generally do not ever need to specify it. That's it.
The BND library underlying the plugin defines instructions to direct its functionality. For this Maven plugin, these instructions are issues in the plugin configuration section of the POM file, as was illustrated [above|#simple-example}. BND recognizes three types of instructions:
version=3.0, that can be used with property substitution, but are not copied to the manifest.The remainder of this section covers the most important aspects of BND's instructions; for complete details refer to the BND documentation.
The <Export-Package> instruction is a list of packages for the bundle to export. These packages are copied into the resulting bundle JAR file from the available classes (i.e., project classes, dependencies, and class path); thus, your it is possible to include classes not associated the source files in your project. <Export-Package> can be specified with package patterns using the '*' wildcard. Also, it is possible to exclude packages with negation by starting the package pattern with '!'. Thus, non-negated patterns indicate which of the available packages to include in the bundle, whereas negated patterns indicate which should not be included in the bundle. Currently, the list is ordered and earlier patterns take effect before later patterns (we are planning on changing this in the future so that order is not important).
Following standard OSGi R4 syntax, package patterns can include both directives and attributes, which will be copied appropriately into the generated Export-Package manifest header. The version of packages is determined by examining the source JAR file or from packageinfo files in the package directory.
The Private-Package header lists the packages that the bundle should contain but not export. The method of inclusion is identical to the Export-Package header, the only difference is, is that these packages are not exported. This header will be copied to the manifest. If a package is selected by noth the export and private package headers, then the export takes precedence.
Private-Package= com.*
The Include-Resource instruction makes it possible to include arbitrary resources; it contains a list of resource paths. The resources will be copied into the target jar file. The iclause can have the following forms:
iclause ::= assignment | inline | simple
assignment ::= PATH '=' PATH
simple ::= PATH
inline ::= '@' PATH
In the case of assignment or simple, the PATH parameter can point to a file or directory. The simple form will place the resource in the target JAR with only the file name, therefore without any path components. That is, including src/a/b.c will result in a resource b.c in the root of the target JAR. If the PATH points to a directory, the directory name itself is not used in the target JAR path. If the resource must be placed in a subdirectory of the target jar, use the assignment form. The inline requires a ZIP or JAR file, which will be completely expanded in the target JAR.
Include-Resource: @osgi.jar,
LICENSE.txt,
acme/Merge.class=src/acme/Merge.class
The Import-Package header lists the packages that are required by the contained packages. The default for this header is "*", resulting in importing all referred packages. This header therefore rarely has to be specified. However, in certain cases there is an unwanted import. The import is caused by code that the author knows can never be reached. This import can be removed by using a negating pattern. For example:
Import-Package: !org.apache.commons.log4j
To use this plugin, very little information is required by BND. As part of the Maven integration, the plugin tries to set reasonable defaults for various instructions. For example:
${groupId}.${artifactId}".${groupId}.${artifactId}.*", which copies everything under the project package root into the bundle and exports it.*", which imports everything else not in the bundle.src/main/resources/", which copies the hierarchical contents of this directory into the bundle.${pom.version}" with '-' characters replaced with '.' characters.${pom.name}".${pom.description}".${pom.licenses}".${pom.organization}".Since the plugin creates bundles for OSGi R4, it hard codes Bundle-ManifestVersion to be '2'. Additionally, it generates imports for every export to ensure package substitutability, which is very important when working with collaborating services. It is possible to override any of these values (except Bundle-ManifestVersion) just by specifying the desired value in the plugin configuration section of the POM file.