Project

Profile

Help

Feature #1502

closed

Include OSGi header in the Saxon-HE jar

Added by Romain Deltour about 12 years ago. Updated over 6 years ago.

Status:
Duplicate
Priority:
Low
Assignee:
Category:
Build and release
Sprint/Milestone:
-
Start date:
2012-04-26
Due date:
% Done:

0%

Estimated time:
Legacy ID:
Applies to branch:
Fix Committed on Branch:
Fixed in Maintenance Release:
Platforms:

Description

It would be much useful for OSGi Saxon users if Saxon-HE was natively distributed as an OSGi bundle. This minimally requires adding some unobtrusive headers to the jar's manifest.

Some tools can help doing that automatically at build time (e.g. "bnd", a tool developed by OSGi's former editor Peter Kriens, available both for Maven or Ant). I volunteer to help if needed and if this feature request is accepted (I know OSGi reasonably well, although I'm not an OSGi "guru").


Files

pom.xml (2.04 KB) pom.xml sample POM file to wrap Saxon as an OSGi bundle Romain Deltour, 2012-04-26 15:57
Actions #1

Updated by Michael Kay about 12 years ago

  • Category set to Build and release
  • Assignee set to Michael Kay

Thanks for the suggestion. OSGi is one of a zillion technologies that I have been intending to learn about. At present I simply don't understand what would be required to make Saxon OSGi-aware, and what tests we would have to run to ensure that we get it right. If you can help to educate us, that will be much appreciated.

Actions #2

Updated by Romain Deltour about 12 years ago

There are several levels of OSGi "readiness" (see [1]). The minimal requirement for a library to be an OSGi bundle is to include a set of headers in the manifest.

The library must be given a canonical name (@Bundle-SymbolicName@) and version (@Bundle-Version@). It also usually declares a set of requirements (e.g. what packages it depends on at runtime, using @Import-Package@) and capabilities (e.g. what packages will be visible to other bundles, using @Export-Package@).

To be a good citizen in the OSGi world, the bundle version should follow the rules of Semantic Versioning [2], although I don't think this is a strong requirement (mapping the existing Saxon version directly as the OSGi version would be fine I think).

With this headers baked in the jar, you already provide a lot: Saxon will be recognized by OSGi frameworks as an OSGi bundle and the relevant packages would be visible to OSGi saxon users.

The practical usability of the bundle depends a lot on:

  • the @Import-Package@ (or @Require-Bundle@) header:

    If some of your code depends on a package that you do not import with Import-Package (or is not exposed by a bundle that you require with @Require-Bundle@), it will throw a NoClassDefFoundError at runtime since the bundle's class loader would not know about the classes in that package.

  • the @Export-Package@ header:

    If one of your package is not "exported", it will simply not be visible to OSGi users of your library.

  • sound class loading practices:

    The default class loader of a class will only know about the packages visible to the bundle containing the class, so for instance to the single-argument version of the Class.forName() method may not work as-is if the class to be loaded is in another bundle. Whenever your code do dynamic class loading, you should allow the client code to provide its own class loader or do the class loading itself. More info at [3].

As far as I know, there are no ways to strictly "test" that you do things right, since the content of these headers and your class loading practices depend on what you want to expose to your users.

However, some tools can parse your Java code or bytecode and automatically generate these headers, reducing the risk of missing imports/exports. The bnd tool [4] mentioned above does that. It can be used from a Maven build via the Maven Bundle Plugin [5], and you can get support from the felix-users mailing list [6].

As an example, attached is a POM I use to "OSGify" Saxon: I inline the Saxon-HE dependency in this Maven project with packaging type "bundle" and finely configure the imports/exports in the maven-bundle-plugin configuration. The usage would be slightly different within Saxon's native POM, since you would not use this dependency-embedding instruction, but I just thought you might be interested at having a look. Also, the fine configuration of imports/exports might have to be improved for broader use, the OSGified Saxon my POM produces just works well for my needs.

Let me know if I can assist or provide some more pointers (I'm aware that's a lot of information to grok).

A next level of OSGi "readiness" would be to expose part of Saxon's functionality as OSGi "services", but that's definitely not required from the get-go and would require more thinking (what classes to expose ? how to react to life cycle events ?).

[1] http://njbartlett.name/2010/08/24/osgi-compliance-levels.html

[2] PDF: http://www.osgi.org/wiki/uploads/Links/SemanticVersioning.pdf

[3] http://njbartlett.name/2010/08/30/osgi-readiness-loading-classes.html

[4] http://www.aqute.biz/Bnd/Bnd

[5] http://svn.apache.org/repos/asf/felix/releases/maven-bundle-plugin-2.3.7/doc/site/index.html

[6] http://felix.apache.org/site/mailinglists.html

Actions #3

Updated by Michael Kay about 12 years ago

Thanks for the input.

How does one handle optional dependencies, i.e. libraries such as JDOM or Stax that are only invoked on some paths?

The testing angle worries me rather. It took several iterations to get our manifests right for things like the JAXP classpath search (partly because the specs didn't match the implementation in some cases, but more because we shipped it effectively without testing. We get a lot of hassle with things like custom ClassLoader environments (e.g. Eclipse) where the only way to get our class loading right seems to be trial and error.

Actions #4

Updated by Romain Deltour about 12 years ago

How does one handle optional dependencies, i.e. libraries such as JDOM or Stax that are only invoked on some paths?

In a ideal world, JDOM/Stax/XOM- specific functionality would be in separate bundles (i.e. separate jars)

That said, a satisfying practical solution is to declare the imported packages as optional (@resolution:=optional@, see how I do that in the POM previously attached).

The testing angle worries me rather. It took several iterations to get our manifests right for things like the JAXP classpath search (partly because the specs didn't match the implementation in some cases, but more because we shipped it effectively without testing. We get a lot of hassle with things like custom ClassLoader environments (e.g. Eclipse) where the only way to get our class loading right seems to be trial and error.

I guess you would need some integration tests to test your library in some OSGi environments. To do that, one popular option is PAX Exam , which can run integration tests in various OSGi frameworks (e.g. Eclipse Equinox, Apache Felix) and integrates well with Maven.

Such integration tests could for instance assert that code using JDOM/etc works well on OSGi, that extension functions work, etc.

Obviously it first requires a manual inspection of what needs to be tested. I believe it is hard to avoid a trial and error step, simply because there are no tools (that I know of) that can analyze test coverage of class-loading issues. This can vary too much from use cases to use cases.

Actions #5

Updated by Michael Kay over 6 years ago

  • Status changed from New to Duplicate

Duplicate of bug 3328

Please register to edit this issue

Also available in: Atom PDF