Skip to content

Translate Scala-style version numbers for OSGi #15

@szeiger

Description

@szeiger

The current direct translation from Scala-style version numbers (as used for publishing in Maven repositories) to OSGi version numbers makes it difficult to get import version ranges right.

For instance, this is what we now do in slick-extensions:

  OsgiKeys.importPackage := Seq(
    osgiImport("scala.slick*", slickVersion, requireMicro=true),
    osgiImport("scala*", scalaVersion.value),
    "*"
  )

Where osgiImport is defined as:

  /** Create an OSGi version range for standard Scala / Typesafe versioning
    * schemes that describes binary compatible versions. */
  def osgiVersionRange(version: String, requireMicro: Boolean = false): String =
    if(version contains '-') "${@}" // M, RC or SNAPSHOT -> exact version
    else if(requireMicro) "${range;[===,=+)}" // At least the same micro version
    else "${range;[==,=+)}" // Any binary compatible version

  /** Create an OSGi Import-Package version specification. */
  def osgiImport(pattern: String, version: String, requireMicro: Boolean = false): String =
    pattern + ";version=\"" + osgiVersionRange(version, requireMicro) + "\""

This means that slick-extensions 2.0.2 imports slick [2.0.2,2.1) and slick-extensions 2.1.0 imports slick [2.1.0,2.2), which are the defined binary compatible versions. When we look at non-release versions (which have no binary compatibility guarantees), this also works fine: slick-extensions 2.1.0.M1 imports slick 2.1.0.M1.

Combining either multiple release versions, or multiple non-release versions in a container also poses no problems, but things break down when you try to mix release and non-release versions like slick-extensions 2.1.0.M1 and 2.1.0 because 2.1.0.M1 is matched by [2.1.0,2.2) even though it is incompatible and older than 2.1.0.

I think sbt-osgi would be a good place to solve this for all Scala libraries. It could translate the version from the sbt build to an OSGi version for the bundle and the exported packages, and do the same to dependency versions (or is that fully handled by bnd?).

I have some ideas how a suitable version number scheme could look but I'm sure this problem has already been solved by the OSGi community, so I'll leave it to others to suggest something.

As far as I can tell, the challenges are:

  • How to translate Maven version numbers (including milestones, RCs and possibly snapshots) into OSGi version numbers so that binary compatibility can be specified correctly
  • What are the implications of having different version numbers for the bundle + packages and the JARs in a Maven repo? Will this negatively affect discovery of packages?
  • Bonus: Define the translation scheme such that the standard version range [==,+) can be used.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions