You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 5 Next »

This page explores versioning of Tuscany modules and 3rd party libraries distributed with Tuscany. The description below assumes that each Tuscany module is converted into one OSGi bundle and that each 3rd party library is converted into OSGi bundle. The ongoing discussion on the shape of Tuscany distributions will impact versioning, but as long as entities that require to be versioned are available as OSGi bundles, these examples will be relevant. At least for 3rd party libraries, we should definitely provide one bundle per jar to enable versioning that is compatible with 3rd party bundles from other OSGi repositories.

Tuscany and applications inside an OSGi runtime

In the earlier discussions, there was some confusion about whether we expect our users to view Tuscany as in Figure 1) or in Figure 2).

In the figure above, Tuscany is a black box (ok, a blue one) which has been OSGi-enabled at a fine grained level. Tuscany modules and 3rd party libs are all individual bundles, with proper versions, and multiple extensions can execute using different versions of 3rd party libs side-by-side. So Tuscany now has the full benefits of OSGi. From an application developer's point of view, Tuscany is a big blob that provides the Tuscany SPI/SCA API. Everything else is internal to Tuscany. If an application wants to use Axis, it will install a different copy of it. So applications will not accidentally use Tuscany's 3rd party jars. And Tuscany also will not accidentally use other 3rd party jars bundle-ized elsewhere. Tuscany's imports and exports are guarded with Tuscany-specific attributes in this case. IMO this is not good practice in OSGi - Tuscany is not being a good citizen.

Figure 2) also uses exactly the same set of bundles as Figure 1), but in this case there are no Tuscany-specific attributes. 3rd party bundles are potentially shared across applications and Tuscany when import version ranges match. Some of this sharing may not be intentional. Tuscany has to interoperate with bundles from elsewhere, and Tuscany's 3rd party bundles should interoperate with applications. For 3rd party jars which are used to share classes between applications and Tuscany, this is the only option. IMO we should use 2) rather than 1).

Versioning bundles in Tuscany

Export versions

This is the easy part. Tuscany's own exports will use the Tuscany version (eg.1.2.1). 3rd party jars will export using their jar versions (eg. Jaxb-impl-2.6.1.jar will provide packages with version 2.6.1)

Import version constraints (and "uses" constraints on export statements)

How complicated can it be? We have version numbers across all jars and bundles and we want to put sufficient restrictions in place to use appropriate versions of jars. For small applications, versioning is not a big deal at all, and can be easily handled using defaults from tools. But for something the size of Tuscany with nearly 150 third party libraries which is used to assemble applications which may use some of these jars for other purposes, import versioning can indeed be extremely complex.

Let us start with a (simple) scenario:

I start building an application with the dependencies on the left in mind. Tuscany was built with the dependencies on the right in mind. I now put the two together. What classes from which classloaders do we actually see in the OSGi runtime? The answer is "It depends". Import versioning is critical in deciding what amount of sharing of bundles (and hence classes) is allowed between a) Tuscany modules and 3rd party libs, b) Tuscany modules and applications c) applications and 3rd party libs d) between 3rd party libs. Import versioning also defines the range of different versions of bundles that can execute side-by-side within a single OSGi runtime. And these two are conflicting requirements.

Broad version ranges in imports

This is the default used by most tools like maven-bundle-plugin, and other versions of 3rd party libraries from repositories like SpringSource also make version ranges in imports as broad as possible. OSGi spec says: "the import should be as unconstrained as possible to allow the resolver maximum flexibility". So what does this really mean?

Let's look at the example from Fig 3.
Tuscany imports Axiom API using an import statement like:

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

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.

Narrow version ranges in imports

  • No labels