DUE TO SPAM, SIGN-UP IS DISABLED. Goto Selfserve wiki signup and request an account.
...
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.
| Info |
|---|
If you have questions about the maven-bundle-plugin please read the FAQ first. If you still have questions you can ask them on the Felix user list. |
NOTE: test scoped NOTE: only compile, runtime and system scoped dependencies are passed to BND. Provided and test dependencies are not included in the classpath seen by BND.
Since the 1.4.0 release, this plugin also aims to automate OBR (OSGi Bundle Repository) management. It helps manage a local OBR for your local Maven repository, and also supports remote OBRs for bundle distribution. The plug-in automatically computes bundle capabilities and requirements, using a combination of Bindex and Maven metadata.
| Tip |
|---|
Standard Maven Documentation is now available for maven-bundle-plugin 2.3.7 |
| Tip |
|---|
A complete list of instructions and their format is available from the BND website |
| Anchor | ||||
|---|---|---|---|---|
|
...
<Bundle-SymbolicName>is computed using the shared Maven2OsgiConverter component, which uses the following algorithm:
Get the symbolic name as groupId + "." + artifactId, with the following exceptions:- if artifact.getFile is not null and the jar contains a OSGi Manifest with Bundle-SymbolicName property then that value is returned
- if groupId has only one section (no dots) and artifact.getFile is not null then the first package name with classes is returned. eg. commons-logging:commons-logging -> org.apache.commons.logging
- if artifactId is equal to last section of groupId then groupId is returned. eg. org.apache.maven:maven -> org.apache.maven
- if artifactId starts with last section of groupId that portion is removed. eg. org.apache.maven:maven-core -> org.apache.maven.core
<Export-Package>is assumed to be "<Bundle-SymbolicName>.*", unless<Private-Package>is specified, then<Export-Package>is assumed to be empty.- The computed symbolic name is also stored in the
$(maven-symbolicname)property in case you want to add attributes or directives to it.
- The computed symbolic name is also stored in the
<Export-Package>is now assumed to be the set of packages in your local Java sources, excluding the default package '.' and any packages containing 'impl' or 'internal'.
(before version 2 of the bundleplugin it was based on the symbolic name)- Since 2.2.0 you can also use {
local-packages} inside<Export-Package>and it will be expanded to the set of local packages. <Private-Package>is now assumed to be the set of packages in your local Java sources (note that any packages in both<Export-Package>and<Private-Package>will be exported).
(before version 2 of the bundleplugin it was<Private-Package>is assumed to be empty by default.)<Import-Package>is assumed to be "*", which imports everything referred to by the bundle content, but not contained in the bundle.
Any exported packages are also imported by default, to ensure a consistent class space.<Include-Resource>is generated from the project's Maven resources, typically "src/main/resources/", which will copy the specified project directory hierarchy into the resulting bundle JAR file, mirroring standard Maven behavior.<Bundle-Version>is assumed to be "${pom.version}" with '-' character separator of the qualifier replaced with a '.' characterpom.version}" but is normalized to the OSGi version format of "MAJOR.MINOR.MICRO.QUALIFIER", for example "2.1-SNAPSHOT" would become "2.1.0.SNAPSHOT".<Bundle-Name>is assumed to be "${pom.name}".<Bundle-Description>is assumed to be "${pom.description}".<Bundle-License>is assumed to be "${pom.licenses}".<Bundle-Vendor>is assumed to be "${pom.organization.name}".<Bundle-DocURL>is assumed to be "${pom.organization.url}".
...
| No Format |
|---|
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>my-osgi-bundles</groupId>
<artifactId>examplebundle</artifactId>
<packaging>bundle</packaging> <!-- (1) -->
<version>1.0</version>
<name>Example Bundle</name>
<dependencies>
<dependency>
<groupId>org.apache.felix</groupId>
<artifactId>org.osgi.core</artifactId>
<version>1.0.0</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin> <!-- (2) START -->
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<extensions>true</extensions>
<configuration>
<instructions>
<Export-Package>com.my.company.api</Export-Package>
<Private-Package>com.my.company.*</Private-Package>
<Bundle-Activator>com.my.company.Activator</Bundle-Activator>
</instructions>
</configuration>
</plugin> <!-- (2) END -->
</plugins>
</build>
</project>
|
...
| Code Block | ||||
|---|---|---|---|---|
| ||||
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<executions>
<execution>
<id>bundle-manifest</id>
<phase>process-classes</phase>
<goals>
<goal>manifest</goal>
</goals>
</execution>
</executions>
<configuration>
<supportedProjectTypes>
<supportedProjectType>jar</supportedProjectType>
<supportedProjectType>bundle</supportedProjectType>
<supportedProjectType>war</supportedProjectType>
</supportedProjectTypes>
<goal>manifest</goal><instructions>
</goals>!-- ...etc... -->
</execution>instructions>
</executions>
<configuration>
<supportedProjectTypes>
<supportedProjectType>jar</supportedProjectType>
<supportedProjectType>bundle</supportedProjectType>
<supportedProjectType>war</supportedProjectType>
</supportedProjectTypes>configuration>
</plugin>
|
You'll also need to configure the other plugin to pick up and use the generated manifest, which is written to ${project.build.outputDirectory}/META-INF/MANIFEST.MF by default (unless you choose a different manifestLocation in the maven-bundle-plugin configuration). Continuing with our WAR example:
| Code Block |
|---|
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-war-plugin</artifactId> <configuration> <instructions><archive> <!-- ...etc... --><manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile> </instructions>archive> </configuration> </plugin> |
...
bundle- build an OSGi bundle jar for the current project
configuration options:manifestLocationdefaults to ${project.build.outputDirectory}/META-INFunpackBundleunpack bundle contents to output directory, defaults to falseexcludeDependenciescomma-separated list of dependency artifactIds to exclude from the classpath passed to Bnd (use "true" to exclude everything), use "true" to exclude everything.
Version 2 of the bundleplugin now supports the same style of filter clauses inexcludeDependenciesasEmbed-Dependency.classifierattach bundle to the project using the given classifiersupportedProjectTypesdefaults to "jar","bundle"
...
| No Format |
|---|
dependencies ::= clause ( ',' clause ) *
clause ::= MATCH ( ';' attr '=' MATCH | ';inline=' inline )
attr ::= 'groupId' | 'artifactId' | 'version' | 'scope' | 'type' | 'classifier' | 'optional'
inline ::= 'true' | 'false' | PATH ( '|' PATH ) *
MATCH ::= <globbed regular expression>
PATH ::= <Ant-style path expression>
|
...
The MATCH section accepts alternatives, separated by |, and can be negated by using ! at the beginning of the MATCH. Use * to represent zero or more unknown characters and ? to represent a single unknown zero or one character. You can also use standard Java regexp constructs. There is no need to escape the . character inside MATCH. The first MATCH in a clause will filter against the artifactId.
...
| Code Block | ||||
|---|---|---|---|---|
| ||||
<!-- embed all compile and runtime scope dependencies --> <Embed-Dependency>*;scope=compile|runtime</Embed-Dependency> <!-- embed any dependencies with artifactId junit and scope testruntime --> <Embed-Dependency>junit;scope=test<runtime</Embed-Dependency> <!-- inline all non-pom dependencies, except those with scope testruntime --> <Embed-Dependency>*;scope=!runtime;type=!testpom;inline=true</Embed-Dependency> <!-- embed all compile and runtime scope dependencies, except those with artifactIds in the given list --> <Embed-Dependency>*;scope=compile|runtime;inline=false;artifactId=!cli|lang|runtime|tidy|jsch</Embed-Dependency> <!-- inline contents of selected folders from all dependencies --> <Embed-Dependency>*;inline=images/**|icons/**</Embed-Dependency> |
...
Sometimes you would like to clean your local OBR because it contains bundles that are no longer in your local Maven repository. This case often occurs when artifacts were deleted manually. The maven-bundle-plugin provides a simple goal to check for missing bundles, and remove them from the local OBR., and remove them from the local OBR.
configuration:
- obrRepository path to local OBR, defaults to <local-maven-repository>
/repository.xml
Example:
| No Format |
|---|
mvn bundle:clean
|
bundle:index
The index goal allows the creation of an OBR repository based on a set of jars in a maven repository.
Configurationconfiguration:
- obrRepository path to local OBR, defaults to <local-maven-repository>
/repository.xml
Example:
...
- urlTemplate template for generating urls for OBR resources
- mavenRepository path to the maven repository, defaults to <local-maven-repository>
Possible values for the urlTemplate are:
- maven this will create a maven based url such as
mvn:groupid/artifactid/version - pattern with the following placeholders:
%vbundle version%sbundle symbolic name%ffile name%pfile path
Concurrent updates
With a remote OBR, several uploads may occur at the same time. However, the remote OBR is centralized in one file, so concurrent modification must be avoided. To achieve this, the plug-in implements a locking system. Each time the plug-in tries to modify the file it sets a file based lock. If it can't take the lock, it will wait and retry. After 3 attempts the upload process fails. To bypass this lock add -DignoreLock to the command-line (or add <ignoreLock>true<ignoreLock> to the configuration section of your Pom).
...