Dan Gravell
Dan Gravell

Reputation: 8275

Should OSGi fragments export packages contributed to their host?

I noticed a fragment I have uses a Export-Package directive for the package that is contributed to its host:

Fragment-Host: org.eclipse.jetty.osgi.boot
Export-Package: org.eclipse.jetty.osgi.boot.utils;version="1.0.1.felix"
-buildpath: osgi.core;version=4.3.0,\
    org.eclipse.jetty.osgi.boot;version=7.6.1.v20120215
-sources: false
Import-Package: !org.eclipse.jetty.osgi.boot.utils.internal,\
    *

This bundle contributes some extra classes into the org.eclipse.jetty.osgi.boot.utils package in the host.

Ideally I think I should strive to keep packages private where possible, but what about this case? None of the rest of my code requires org.eclipse.jetty.osgi.boot.utils.

Upvotes: 2

Views: 965

Answers (2)

Fr Jeremy Krieg
Fr Jeremy Krieg

Reputation: 593

The accepted answer of @balazs-zsoldos:

Fragment bundles cannot override the classes of the host bundle

...is correct in this specific case, but it is not true in general. A more nuanced answer would be that fragments cannot override the host bundle's classes unless the host bundle has been configured to allow it (which in your case the org.eclipse.jetty.osgi.boot bundle is not).

The way you configure the host bundle to allow it is by using the Bundle-ClassPath header. Let's assume you have a host bundle A with an attached fragment B, and A has the following manifest entry:

Bundle-ClassPath: contrib,.

Suppose the bundle classloader is asked to look for class pack.Z in bundle A. The bundle classloader will search in the following order:

  1. A:contrib/pack/Z.class
  2. B:contrib/pack/Z.class
  3. A:pack/Z.class
  4. B:pack/Z.class

So you can see that if your contrib directory in A is empty or non-existent, then the bundle classloader will try and load B:contrib/pack/Z.class before it will try and load A:pack/Z.class. But as you can see, this is only possible if A was explicitly built to allow it.

Upvotes: 0

Balazs Zsoldos
Balazs Zsoldos

Reputation: 6046

From the OSGi core specification (6.0):

A host bundle's class path is searched before a fragment's class path.

"This bundle contributes a new org.eclipse.jetty.osgi.boot.utils with classes that override those of the host"

Fragment bundles cannot override the classes of the host bundle (if that was what you meant).

If a package is not intended to use by other bundles, it should not be exported. The host bundle can see the classes and resources of its attached fragment bundle, but only if it does not have the same class or resource.

Upvotes: 3

Related Questions