Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Let's look at the example from Fig 3.

Tuscany imports Axiom API using an import statement like:

...

This means that the version range of Axiom that Tuscany supports is "1.2.5 to infinity". Typically users will have only version 1.2.5 in their OSGi runtime, and that is the version that will be used. The application in Fig 3 however has another copy of this bundle which is at version 1.3. As shown in Fig 4, we now have Tuscany wired to Axiom version 1.3 (which may or may not be the desired outcome in this case). This sharing implies that App A and Tuscany can share Axiom classes. Similary Tuscany's extensions share Jaxb classes.

The broader the version range, the higher the class sharing that is enabled. Since we still have 3rd party libraries which rely on thread context classloaders which dont fit in with OSGi modularity/versioning, a broad range in import versioning reduces the risk of classloading errors arising from multiple definitions of a class in different classloaders.

But there is a negative side - as shown in Figure 4, we are preventing side-by-side execution of different versions of jaxb.

Another scenario is upgrading one 3rd party library in Tuscany. An user wants to migrate Tuscany to using version 1.4 of Axiom. A flexible versioning system enables the user to just install the new version of Axiom, without any changes to Tuscany bundles. eg. An user can get Axiom 1.4 from SpringSource and easily run it with Tuscany without waiting for the next release of Tuscany that ships with Axiom 1.4.

Narrow version ranges in imports

We can make version ranges in imports as narrow as possible eg. only support one version.

No Format

Import-Package: org/apache/axiom/soap;version="[1.2.5,1.2.5]"

The result is shown in Figure 5. Sharing of bundles only takes place for exact versions. More versions can now execute side-by-side. eg. Two Tuscany extensions can now run using different versions of jaxb. But these two extensions cannot share any jaxb classes.

Back to the scenario where an user wants to migrate to a later version of a 3rd party library like 1.4 of Axiom. The narrow version range in Tuscany imports essentially means that the user has to modify every single Tuscany bundle to import version 1.4 of Axiom.

So narrow version ranges can reduce class sharing and increase side-by-side execution, but that also make upgrades difficult, introduce more number of classes loaded in the system, and can result in classloading exceptions resulting from multiple definitions of classes. TCCL based classloading can potentially lead to problems.

Wiki Markup
Figure 4) and Figure 5) are showing the two extremes, the version range we want may be somewhere in between. eg. By using the version range \[1.2.5,2.0.0) of Axiom, Tuscany will be importing any version of Axiom within this major version 1, and preventing importing of the next major version 2, which may contain breaking changes.

If you have actually read this far, you must be patient. I will try to summarize the points that we need to consider.

Points to consider for versioning 3rd party libs

  1. What is the minimum version that Tuscany will work against? Can we assume that the currently used version is the lowest supported?
  2. What is the maximum version that Tuscany will work against? Can we assume that all the APIs we use will remain backward compatible? For a generic versioning scheme which doesn't involve looking at every single one of the 149 libs, the choices for max version are
    1. current version
    2. any minor version with the current major version
    3.  infinity
  3. What are the third party libs where classes are shared between applications and Tuscany?
  4. For  libraries in 3) what are the versioning requirements? Min version? Max version?
  5. Does Tuscany have extensions which require different versions of a 3rd party lib? If so these should use very narrow version ranges to enable the libs to coexist.
  6. Are there applications which require different versions of a 3rd party lib from Tuscany? If so, should we use very narrow version ranges to enables these libs to co-exist?
  7. Do we want to be consistent with bundles from other sources? SpringSource? ServiceMix? Any others?

Implementation steps?

  1. One bundle per Tuscany module, one bundle per 3rd party lib
    • Based on the discussion on aggregating modules into larger bundles, the Tuscany bundling may change.
  2. All Tuscany modules export packages at Tuscany version (eg. 1.4.0), all third party libs export packages at their jar version.
  3. All bundles with exports will also import those packages using the same version range as other importers  (OSGi best practice)
  4. Imports and "uses" statements in exports
    1. Minimum version: same as currently used version in Tuscany
    2. Maximum version - use defaults in the first instance for all 3rd party libs (ie. maximum version is infinity).
    3. Wiki Markup
      Move to maximum version under current major version, Eg. Jaxb 2.1.6 will be imported using version range \[2.1.6,3.0.0)
    4. Fine tune further to narrow down version ranges for specific third party libs as we learn more.

We can implement 1, 2, 3, 4.1 and 4.2 to start with since they are easy to do with current tooling.