BND, Self-Imports and SNAPSHOT versions

First, let’s define what this post achieves.

You want to customize the way the Maven Bundle plug-in (or BND) write version ranges for Import-Package properties in your MANIFEST. Let’s suppose your project depends on package org.toto in version 1.1.

The import range will look like org.toto;version="[1.1,2.0)".
Assuming you want a range like org.toto;version="[1.1,1.2)", you will have to put the following configuration in your POM.

<plugin>
	<groupId>org.apache.felix</groupId>
	<artifactId>maven-bundle-plugin</artifactId>
	<configuration>
		<instructions>
			<Import-Package>
				org.toto.*;version="${range;[==,=+)}",
				*
			</Import-Package>
		</instructions>
	</configuration>
</plugin>

This will work well if this package is only exported by a dependency. Indeed, with the range directive used this way, the package version is guessed.

Now, let’s suppose the bundle that imports this package also exports it (or a sub-package). Well, you will get a surprise. The version range will not be replaced by BND (at least, with the Maven Bundle plugin 2.3.4 – maybe more recent versions throw an error). But you can specify a version with…

org.toto.*;version="${range;[==,=+);1.1.1}"

This will work because this version, 1.1.1, is compliant with OSGi’s versionning. Let’s now assume you now want to inject your Maven version instead.

org.toto.*;version="${range;[==,=+);${project.version}}"

That will not work.
You will get a build failure with a message like…

Invalid syntax for version: 1.1-SNAPSHOT, for cmd: range, arguments; [range, [==,=+), 1.1-SNAPSHOT]

To solve that, you will need to use another BND directive, maven_version, that converts the Maven version into an OSGi version. Which gives…

org.toto.*;version="${range;[==,=+);$(maven_version;${project.version})}",

I know. It’s scary… but it works.
Now that I have written this article, I need to check if the problem persists with more recent versions of the Maven bundle plugin.


About this entry