The bnd-baseline-maven-plugin
is a bnd based plugin that verifies OSGi
bundles correctly obey semantic versioning rules. If the bundle does not
correctly follow the rules then the build will fail.
This plugin performs version metadata validation by comparing the bundle that has just been built against a previously released version, known as the baseline. Where differences exist the plugin scans the class bytecode to determine whether the changes are backward compatible or not, and suggests updated versions for the packages and bundle.
If the newly built project has not increased the version(s) of the
affected package(s) then the verification of the bundle will fail. In
this way the bnd-baseline-maven-plugin
can be used to guarantee that
semantic versioning policies are correctly followed.
Normally you will add the bnd-baseline-maven-plugin
directly to the
build of your OSGi bundle.
<plugin>
<groupId>biz.aQute.bnd</groupId>
<artifactId>bnd-baseline-maven-plugin</artifactId>
<version>${bnd.version}</version>
<configuration>...</configuration>
<executions>
<execution>
<id>baseline</id>
<goals>
<goal>baseline</goal>
</goals>
</execution>
</executions>
</plugin>
The only goal of the bnd-baseline-maven-plugin
is baseline
which verifies the
OSGi bundle. By default the bnd-baseline-maven-plugin
binds to the
verify
phase of your build.
The bnd-baseline-maven-plugin
outputs any encountered versioning errors to the
build log.
The Semantic Versioning Whitepaper
defines the rules for semantic versions. In summary for a version X.Y.Z
:
- A change which breaks backward compatibility for consumers necessitates a major version change
(i.e. the new version is
X+1.0.0
). - A change which remains backward compatible for consumers but is breaking for providers necessitates a minor version change (i.e. the new version is
X.Y+1.0
). - A change which is compatible for all, consumer and provider alike, necessitates a micro version change
(i.e. the new version is
X.Y.Z+1
)
In general a Provider is a person implementing an API and a *Consumer is a person using the API, and there are many more consumers than providers. Note that this is not the same as saying "The person who implements the interface is the provider".
A good example is the Servlet API. Obviously Jetty and TomCat are providers of the Servlet API, while
WAR files are Consumers of the Servlet API. This is true even though WAR files contain Servlets, and
Servlets implement the javax.servlet.Servlet
interface.
In the case of the Servlet API adding a method to the ServletContext would be a minor change because it only requires an update to TomCat and Jetty. Adding a method to the Servlet interface, however, would break all WAR files and therefore be a major change.
The distinction between interfaces designed for providers to implement (like javax.servlet.ServletContext
)
and those designed for consumers (like javax.servlet.Servlet
) can be made using the
org.osgi.annotation.versioning.ProviderType
and org.osgi.annotation.versioning.ConsumerType
annotations
The bnd-baseline-maven-plugin
typically requires no configuration. By
default the plugin will search the available maven repositories for
artifacts with the same group id and artifact id as the current module,
and with a version less than the current module version. The highest
version artifact which matches these rules will be used as the baseline.
By default the bnd-baseline-maven-plugin
will use information from the
current project to set its search parameters, however sometimes an artifact
will move or change name over time, or a particular version should be
targeted. In this case the search parameters can be overridden through baseCoordinates
(since version 7.0.0)
or base
(the former taking precedence). If a
search parameter is omitted then it will take its default value:
<configuration>
<baseCoordinates>${a.different.groupId}:${a.different.artifactId}:${single.version.or.version.range}</baseCoordinates>
</configuration>
or
<configuration>
<base>
<groupId>${a.different.groupId}</groupId>
<artifactId>${a.different.artifactId}</artifactId>
<version>${single.version.or.version.range}</version>
<classifier>${an.optional.classifier}</version>
<extension>${an.optional.extension}</extension>
</base>
</configuration>
N.B. The default version range is (,${project.version})
, i.e. all versions
up to but not including the current version. Whilst the base version search
parameter is usually a version range a fixed version, e.g. 1.2.3
,
may also be used in the configuration.
By default the bnd-baseline-maven-plugin
will fail the build if it cannot
locate a baseline. Sometimes (for example if a project has never been
released before) then there isn't a baseline to use. This failure can
be disabled as follows:
<configuration>
<failOnMissing>false</failOnMissing>
</configuration>
By default the bnd-baseline-maven-plugin
will include repositories
listed in the Distribution Management section of the POM when
searching for the baseline. This is usually the right choice as the
distribution repository does not normally change between releases.
This behaviour can be disabled as follows:
<configuration>
<includeDistributionManagement>false</includeDistributionManagement>
</configuration>
By default the bnd-baseline-maven-plugin
will fail the build if a
verification error is encountered. Sometimes it is preferable to issue
warnings, rather than failing the build. In this case the plugin can
be configured as follows:
<configuration>
<continueOnError>false</continueOnError>
</configuration>
By default the bnd-baseline-maven-plugin
will only output version
information in cases where the version has not been incremented
sufficiently. If the user wishes to output full details of the baseline
calculation then this can be configured as follows:
<configuration>
<fullReport>true</fullReport>
</configuration>
The names of the exported packages in the bundle to baseline. The default is all the exported packages but this property can be used to specify which exported packages are baselined.
<configuration>
<diffpackages>
<diffpackage>!*.internal.*</diffpackage>
<diffpackage>*</diffpackage>
</diffpackages>
</configuration>
The manifest header names and resource paths to ignore when baseline comparing. This property can be used to exclude items from baseline comparison.
<configuration>
<diffignores>
<diffignore>com/foo/xyz.properties</diffignore>
<diffignore>Some-Manifest-Header</diffignore>
</diffignores>
</configuration>
Although the semantic versioning policy enforces also to maintain semantic bundle versions (and not only semantic package versions), this is often not followed by projects for different reasons.
It is possible to only check for correct package versions and leave out the bundle version by ignoring the Bundle-Version
manifest header.
<configuration>
<diffignores>
<diffignore>Bundle-Version</diffignore>
</diffignores>
</configuration>
Note though that this will also completely ignore package removals, as in that case the package version from the base would need to be compared with the (ignored) bundle version, as the version of the deleted package is obviously no longer there.
Configuration Property | Description |
---|---|
baseCoordinates |
The Maven coordinates of the base artifact in the format <groupId>:<artifactId>[:<extension>[:<classifier>]]:<version>} . If set, takes precedence over base . Override with property bnd.baseline.base.coordinates . Available since version 7.0.0 |
base |
See Changing the baseline search parameters. Defaults to the highest version of the project's artifact that is less than the version of the project's artifact. |
failOnMissing |
See Fail on missing baseline. Defaults to true . Override with property bnd.baseline.fail.on.missing . |
includeDistributionManagement |
See Include Distribution Management. Defaults to true . Override with property bnd.baseline.include.distribution.management . |
fullReport |
See Full Reporting. Defaults to false . Override with property bnd.baseline.full.report . |
diffpackages |
See Diffpackages. Defaults to * . Override with property bnd.baseline.diffpackages . |
diffignores |
See Diffignores. Optional. Override with property bnd.baseline.diffignores . |
continueOnError |
See Continue on Error. Defaults to false . Override with property bnd.baseline.continue.on.error . |
skip |
Skip the baseline process altogether. Defaults to false . Override with property bnd.baseline.skip . |
releaseversions |
When searching a version range for the baseline, only consider release versions. That is, don't consider alpha , beta , milestone , or rc versions. snapshot versions are never considered when searching for the baseline. Defaults to false . Override with property bnd.baseline.releaseversions . |
reportFile |
The baseline report is placed in this file. Defaults to ${project.build.directory}/baseline/${project.build.finalName}.txt . Override with property bnd.baseline.report.file . |