What is the intended use case for Bundle-Classpath in OSGI bundles
Asked Answered
P

3

24

I am trying to understand the intended use case for Bundle-Classpath in OSGI bundles.

Here is my understanding, please help me understand if this is correct.

Let's say I am working on creating an OSGI bundle which will be deployed in an ecosystem of other bundles. The bundle I am working on needs some other bundles, but they are not loaded/exported in this ecosystem, and I do not have control on what the ecosystem exports. In such a scenario, I can put these bundles inside some directory (say 'lib') which becomes part of my bundle. These bundles should also be referenced from the Bundle-Classpath, so they can be loaded.

  • Is this a correct use case for Bundle-Classpath ?
  • Will these additional bundles also be loaded in the OSGI container and will packages exported by them be available to other bundles ?
Pipette answered 5/6, 2013 at 7:27 Comment(0)
A
56

Bundle-ClassPath is intended for including dependencies in our bundle, so that our bundle can be deployed standalone.

Let's take an example. Suppose the code in my bundle uses a library, e.g. Google Guava. I have two choices for packaging my bundle:

  1. Simply create my bundle with only my own code inside it. The bundle will now have the Import-Package statements that declare a dependency on Guava, and anybody who wants to deploy my bundle into his application will also have to deploy Guava.

  2. Alternatively I can include a copy of Guava inside my bundle and reference it from my Bundle-ClassPath. Whoever deploys my bundle can deploy just my bundle, and doesn't need to worry about where to get Guava from. In fact, the existence of Guava inside my bundle is an implementation detail, and the deployer doesn't even need to know that I am using it.

The choice between these two options is a trade-off. Option 2 has the advantage that my bundle is easier to deploy because it is standalone -- everything it needs is right there inside it. On the other hand my bundle is much bigger than it needs to be, which could become a problem if lots of other bundles also embed their own copy of Guava.

A more severe problem with option 2 is that all of the dependencies of the library now become my dependencies as well. Actually Guava is a rare example of a Java library with no dependencies of its own... but many other Java libraries drag in a huge tree of transitive dependencies. If you use this approach with, say, Hibernate then your own bundle will also have that large dependency set. This gets very ugly, very quickly.

So, you should be cautious not to overuse Bundle-ClassPath/Embed-Dependency. You should only consider using it if the dependency is (a) small, and with no transitive dependencies, and (b) your bundle uses the library as an internal implementation detail, i.e. it is not part of your public API.

UPDATE

I forgot to answer your second question about the exports. The answer is NO, the exports of any "bundles" you put on your Bundle-ClassPath will NOT become exports of your own bundle. In fact the JARs we put on Bundle-ClassPath are not treated as bundles at all, they are just JARs.

You can choose to export packages that come from within the JARs on your Bundle-ClassPath but you have to do this in the MANIFEST.MF of your own bundle.

Arian answered 5/6, 2013 at 11:43 Comment(3)
Thanks a ton! Just the explanation I was looking for :-)Pipette
Thanks! Great write up. I would like to recommend a medium article please. :)Selective
Thanks, this saved me, after being stuck on an issue for hours!Charcoal
C
7

The most common use case for this header is the packaging of external libraries. Let's say you have some library foo.jar, and want to use its classes in your bundle.

You put the jar into your bundle like so,

/
  com/company/Activator.class
  foo.jar
  META-INF/MANIFEST.MF

In you manifest, you can now use

Bundle-ClassPath: foo.jar,.

Remember to include the . on the classpath, or you will not be able to find the classes in your bundle.

When classes are on the Bundle-ClassPath, you can use them like any other class: use them in your code, or export them.

Carmelacarmelia answered 5/6, 2013 at 9:45 Comment(5)
When I put a jar (non osgi) on the Bundle-Classpath, do I have to include the classes it imports into my Import-Package statement ?Pipette
No: the classes are treated in exactly the same way as any other in your bundle.Carmelacarmelia
Thanks, then I think it must be the Maven bundle plugin which is forcing me to import the classes used by the jarPipette
Hm, not sure. Try to update your question with the actual layout of your generated bundle, the manifest, and the maven statements you use.Carmelacarmelia
it looks like the Maven Bundle Plugin does require the importing of classes that come in a jar, even if it not an OSGI jar. I will dig in a little deeper and update my question ... thanks!Pipette
I
2

I think you may be a bit off here.

A Bundle-Classpath is an ordered, comma-separated list of relative bundle JAR file locations to be searched for class and resource requests.

What this means is that when some bundle class needs another class in the same bundle, the entire bundle class path of the containing bundle is searched to find the class.

From OSGI in Action.

Let's consider a concrete case. Imagine a bundle (JAR file) with the following structure:

src/a/A.class
src2/b/B.class
src3/c/C.class

if you wanted a.A, b.B and c.C to be available to each other, you'd have to define src, src2 and src3 as pertaining to the bundle classpath. That would mean you'd have to add to your manifest file the following line:

Bundle-ClassPath: src,src2,src3
Incorruption answered 5/6, 2013 at 8:30 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.