43

I'm just getting started with OSGI development and am struggling to understand how best to handle dependant JARs.

i.e. if I'm creating a bundle the likelyhood is that I will need to use a few 3rd party JARs. When I create my bundle JAR to deploy to OSGI, obviously these 3rd party JARs are not included and thus the bundle will not run.

I understand that one option is to turn these JARs into bundles and also deploy them to the OSGI container. However if they only need to be used by the one bundle this doesn't seem ideal.

What is the best solution to this? Can the JARs be embedded within the bundle JAR and if so is this a reasonable approach?

William
  • 13,332
  • 13
  • 60
  • 73

6 Answers6

42

You can include a third party jar inside your bundle by adding the third party jar to the root directory of the bundle jar file and then adding a bundle classpath header to the bundle's manifest, e.g.:

Bundle-ClassPath: .,my3rdparty.jar

If you want to place third party jar to subdirectory, specify the path without using heading ./, e.g

Bundle-ClassPath: .,lib/my3rdparty.jar # (not ./lib/my3rdparty.jar)
Ernest Friedman-Hill
  • 80,601
  • 10
  • 150
  • 186
William
  • 13,332
  • 13
  • 60
  • 73
  • Thought I'd add this answer as it's a solution I found on the web and was able to quickly get working. However I appreciate the opinions with regard to the advantage of properly deploying the JARs as bundles. – William Aug 27 '09 at 16:51
  • There should be comma instead of semicolon as classpath separator – Kojotak May 10 '12 at 13:07
  • 4
    Keep in mind this might result in CLassCastExceptions if one of the objects in the Bundle-Classpath is used in another bundle that declares its own Bundle-Classpath since their classloader will be different – Hilikus Jun 30 '14 at 19:25
  • 1
    I think this is a good compromise when you want to extend a Bundle based on legacy services and it relies on a finite set of proprietary JAR files. – Carlos Apr 05 '16 at 18:21
  • Please avoid this pattern. Each jar should have self bundle. OSGi is modular system. It is about scalability. – user1722245 Oct 23 '18 at 18:20
28

I would almost always bundle each jar separately. OSGi itself is meant for modularization and you take the whole system ad absurdum by not doing this.

If you want to convert JARs into bundles you might want to use the BND Tool written by Peter Kriens. But first I would suggest you look for the bundle in the SpringSource Enterprise Bundle Repository if they haven't already done the work for you.

Gary Sheppard
  • 4,764
  • 3
  • 25
  • 35
Roland Schneider
  • 3,615
  • 3
  • 32
  • 43
  • If you are looking for a mainstream open source library, I'd place good money on the Spring guys having it available from their repository. – SteveD Sep 02 '09 at 08:59
  • You should also avoid embedding since it can result in strange behavior at times. – Thirlan Feb 06 '12 at 15:08
  • Today many of the lbis you need already are bundles so the first place to look for me is the maven central repo. If the main distribution of the lib is not yet a bundle it also makes sense to look in the servicemix bundles in central. – Christian Schneider May 21 '12 at 10:44
9

It is possible to embed non-OSGi dependencies into the bundle.

An easy way to do this is to use Maven to manage your dependencies and Maven Bundle Plugin to build your bundle. Take a look at the <Embed-Dependency> and <Embed-Transitive> instructions of the Maven Bundle Plugin described in the section Embedding dependencies of the plug-in documentation page.

As Roland pointed out this is not an ideal solution with respect to the intentions of OSGi, i.e. modularization and reuse of individual modules. However it might be pragmatic solution for time being until the 3rd-party dependencies can be converted into OSGi bundles.

Pavol Juhos
  • 1,867
  • 14
  • 15
7

This thread is a bit old, but I wanted to point out one of the limitations of embedding dependencies. Recall that dependencies are at the jar level, but when you export packages some may need to come from the embedded dependencies. If this happens, you will end up with duplicate classes, one set inline in the top level bundle and another in the embedded jar. Of course, you can inline the entire embedded jar, but before you know it this propagates across your entire dependency chain. This is just one of the problems that Roland and others refer to.

Ed Ost
  • 1,399
  • 13
  • 9
4

Here is an example if you are using the Maven Bundle Plugin.

Note: This plugin automatically imports packages that your dependencies need. This may or may not be a problem for you. Thankfully, you can suppress the packages you don't really need to import (see below).

    <Import-Package>
        <!-- this was imported by one of the dependencies; I don't really need it -->
        !org.apache.jackrabbit.test,
        *
    </Import-Package>
    <Include-Resource>
        lib/concurrent-1.3.4.jar,
        lib/jackrabbit-core-2.6.5.jar,
        lib/jackrabbit-spi-2.6.5.jar,
        lib/jackrabbit-spi-commons-2.6.5.jar,
        lib/lucene-core-3.6.0.jar,
        lib/tika-core-1.3.jar
    </Include-Resource>
    <Bundle-ClassPath>
        .,
        concurrent-1.3.4.jar,
        jackrabbit-core-2.6.5.jar,
        jackrabbit-spi-2.6.5.jar,
        jackrabbit-spi-commons-2.6.5.jar,
        lucene-core-3.6.0.jar,
        tika-core-1.3.jar
    </Bundle-ClassPath>
shreyas
  • 700
  • 8
  • 10
-4

Can we use OSGI to override the bootstrap classloader jars loaded during runtime, like if we wanted to override JAXP1.4.5 available with Java7 to JAXP1.6, there is -Dendorese feature to override the default API to upgraded API. Can we able to do this thing with the help of OSGI.

  • 3
    Is this a question or an answer? It seems like another question - in which case you should post it as a separate question rather than as an answer. – Michael.Lumley Mar 24 '15 at 13:07