LibraryToggle FramesPrintFeedback

By default, the Maven bundle plug-in automatically assigns a version range to imported packages, following the semantic versioning rules outlined in Semantic Versioning. You need to provide an additional hint to the bundle plug-in, to indicate whether the bundle imports a package in the role of a consumer or a provider (the bundle plug-in presumes the consumer role).

For automatic import versioning to work, the package dependency must be versioned at build time, otherwise the importing bundle cannot calculate the import range.

[Note]Note

The features described here require Maven bundle plug-in version 2.2.0 or later (which is based on Bnd version 1.15).

Since version 2.2.0, the Maven bundle plug-in automatically generates consumer import ranges that conform to the rules of semantic versioning, as defined in Consumer import range. The only prerequisite is that the corresponding exporter actually defines a package version.

For example, given that the hello-paris bundle consumes version 1.2.1 of the org.fusesource.example.time package, the Maven bundle plug-in automatically generates a manifest with the following import:

Import-Package: org.fusesource.example.time;version="[1.0,2)"

When the API and the provider are to be combined in the same bundle, append the provide:=true clause to the relevant API packages listed in the Export-Package instruction (this is the correct setting to use both for an API/provider combination bundle and for an API/provider build-time combination bundle).

For example, given that the hello-boston bundle includes both the org.fusesource.example.hello.boston API and its implementation classes, you would define the Export-Package instructions for the hello-boston bundle as follows:

<instructions>
  ...
  <Export-Package>
    !${project.groupId}*.impl.*,
    !${project.groupId}*.internal.*,
	${project.groupId}.hello.boston*;provide:=true;version=${project.version}
  </Export-Package>
  ...
</instructions>

Given that the org.fusesource.example.hello.boston package has version 1.0, the Maven bundle plug-in generates a manifest with the following highlighted import and export:

[Note]Note

In the case where the API and the provider code are located in separate Maven projects, setting provide:=true on an exported API package in the provider's POM has the important side-effect that the API interfaces are included in the provider bundle. For a detailed explanation, see API/Provider Build-Time Combination.

Sometimes, a third-party exporter might follow a consistent versioning convention, but this convention is different from the OSGi convention. In this case, it make sense to define a custom import rule that codifies the alternative convention. For example, if a third-party exporter increments the minor version number whenever binary compatibility with consumers is broken, you could use Bnd's range macro to codify this rule on consumer imports, as follows:

<Import-Package><![CDATA[
  com.package.with.wrong.semantics*;version="$<range;[==,=+)>",
  *
  ]]>
</Import-Package>

Where the Bnd macro is written in the format, $<Macro> and must be enclosed in a CDATA section to avoid clashing with the XML interpretations of < and > (actually, Bnd supports a variety of different macro delimiters, most of which cannot be used here: braces, ${...}, clash with Maven properties; while square brackets, $[...], and parentheses, $(...), clash with the syntax of version ranges).

Entries like == and =+ are masks that return a version based on the version of the corresponding exporter. The equals sign, =, returns the corresponding version part unchanged; the plus sign, +, returns the corresponding version part plus one; and the minus sign, -, returns the corresponding version part minus one. For example, if the corresponding exporter has the version, 1.3.0.4, the range mask, [==,=+), resolves to [1.3,1.4). For more details, consult the Bnd documentation for the range macro.

The range macro is a relatively new addition to Bnd. In POMs that were written before the range macro became available, you might come across ranges written using the Bnd version macro. For example, the range, $<range;[==,=+)>, could also be written using the version macro as follows:

<Import-Package><![CDATA[
  com.package.with.wrong.semantics*;version="[$<version;==>,$<version;=+>)",
  *
  ]]>
</Import-Package>
[Note]Note

At the time of writing, the Bnd tool has a bug that causes two NullPointerException exceptions, accompanied by lengthy stack traces, to be generated whenever you build a Maven project featuring the range or version macros as shown above. Although alarming, these exceptions are harmless non-fatal errors. If you check the generated bundle after building, you will see that the Manifest.mf file is generated exactly as specified by the bundle instructions.

Comments powered by Disqus