Search code examples
javaosgircp

RCP ClassNotFoundException with nested jars


I have an RCP application with the following setup:

my.plugin.jar
|-->META-INF
|-----MANIFEST.MF
|-->A1.jar
|-->A2.jar
|-->A_Dependencies.jar (Jar of jars)
|----->X1.jar,X2.jar,...Xn.jar

When I run it I get ClassNotFoundExceptions relating to the nested jars (X1.jar, X2.jar, etc...)

My Manifests contain (among other things) the following entries:

my.plugin.jar
   Bundle-ClassPath: .,A1.jar,A2.jar,A_Dependencies.jar

A1.jar
   Bundle-ClassPath: .,A_Dependencies.jar

A2.jar
   Bundle-ClassPath: .,A1.jar

A_Dependencies.jar
    Bundle-ClassPath: X1.jar, X2.jar,...Xn.jar
    Export-Package: (All the appropriate packages)

How do I properly set up the manifest to resolve these? A sample error would look like:

Caused by: java.lang.ClassNotFoundException: some.package.some.classfile cannot be found by my.plugin
    at org.eclipse.osgi.internal.loader.BundleLoader.findClassInternal(BundleLoader.java:439)

Solution

  • OSGi bundles nested inside another bundle are just considered ordinary jar files. Their manifest will not be picked up, and hence Bundle-ClassPath will not work. If you want to deploy all jars inside one bundle (why not deploy all bundles separately?), you need to flatten the structure so that all your dependency jars are directly under your bundle, and added to the Bundle-ClassPath of your manifest:

    my.plugin.jar
       Bundle-ClassPath: .,A1.jar,A2.jar,X1.jar,...,Xn.jar
    

    From the error message, it seems your are running Equinox. I'm more familiar with Felix, and the maven-bundle-plugin, which can be configured to embed dependencies and add them to the classpath. The bundles created by the plugin are not tied to Felix, so you could take a look at that instead of manually write bundle manifests.