Prev Next

Versioning the Packages

So far we’ve ignored the nasty concept of versions. We were forced to export a lot of packages that are not semanticaly versioned. By default, bnd gives these packages the version of their bundle, which is an awful defaultbut we don’t know any better. In our example, this looks like:

Export-Package
  org.dom4j                              {version=1.6.1, imported-as=\[1.6,2)}
  org.dom4j.bean                         {version=1.6.1}
  org.dom4j.datatype                     {version=1.6.1}
  org.dom4j.dtd                          {version=1.6.1, imported-as=\[1.6,2)}
  org.dom4j.io                           {version=1.6.1, imported-as=\[1.6,2)}
  org.dom4j.rule                         {version=1.6.1, imported-as=\[1.6,2)}
  org.dom4j.rule.pattern                 {version=1.6.1, imported-as=\[1.6,2)}
  org.dom4j.swing                        {version=1.6.1}
  org.dom4j.tree                         {version=1.6.1, imported-as=\[1.6,2)}
  org.dom4j.util                         {version=1.6.1, imported-as=\[1.6,2)}
  org.dom4j.xpath                        {version=1.6.1, imported-as=\[1.6,2)}
  org.dom4j.xpp                          {version=1.6.1, imported-as=\[1.6,2)}
  org.gjt.xpp                            {version=2.1.10, imported-as=\[2.1,3)}
  org.relaxng.datatype                   {version=1.0.0, imported-as=\[1.0,2)}

Sadly, there is no good solution. It is one of those things where only the author can provide good semantic versions, anything someone else does will back fire one day. And this does makes sense because semantic versioning is basically a promise from the author to signal the compatibility of future changes in the version number.

Note that version ranges cannot be added for JRE packages, e.g. javax.swing or org.xml.sax because the Java specifications do not define the version of any of these packages, and therefore the OSGi framework exports them all as version 0.0.0. As an alternative, add a Bundle-RequiredExecutionEnvironment header to indicate the basic Java level required by the bundle:

Bundle-RequiredExecutionEnvironment: J2SE-1.8

Other possible values include JavaSE-1.6, OSGi/Minimum-1.0, etc.

If we wanted to control the versions in more detail we could decorate the Export-Package header. In general you then want to use macros to specify these versions so you won’t have to repeat yourself.

version-dom4j = 1.6.1
version-relaxng = 1.0.0
version-gjt = 2.1.10
Export-Package: \
		org.dom4j.*;version=${version-dom4j}, \
		org.relaxng.datatype;version=${version-relaxng}, \
		org.gjt.xpp;version=${version-gjt}

This gives us an export list of:

Export-Package
  org.dom4j                              {version=1.6.1, imported-as=[1.6,2)}
  org.dom4j.bean                         {version=1.6.1}
  org.dom4j.datatype                     {version=1.6.1}
  org.dom4j.dtd                          {version=1.6.1, imported-as=[1.6,2)}
  org.dom4j.io                           {version=1.6.1, imported-as=[1.6,2)}
  org.dom4j.rule                         {version=1.6.1, imported-as=[1.6,2)}
  org.dom4j.rule.pattern                 {version=1.6.1, imported-as=[1.6,2)}
  org.dom4j.swing                        {version=1.6.1}
  org.dom4j.tree                         {version=1.6.1, imported-as=[1.6,2)}
  org.dom4j.util                         {version=1.6.1, imported-as=[1.6,2)}
  org.dom4j.xpath                        {version=1.6.1, imported-as=[1.6,2)}
  org.dom4j.xpp                          {version=1.6.1, imported-as=[1.6,2)}
  org.gjt.xpp                            {version=2.1.10, imported-as=[2.1,3)}
  org.relaxng.datatype                   {version=1.0.0, imported-as=[1.0,2)}

Whatever you do, the fact that the packages are not versioned by the author makes it a losing game. So this probably works when you use this bundle yourself but it is dangerous to publish it to the world or place it on maven central.


Prev Next