Cannot get typed Instance of class from OSGI bundle

shang tsung :

I have the following situation.I need an instance of class A in my application, and this class A comes from Bundle B (osgi) and is located in package X in that Bundle. What i have done so far: I have added the bundle B to local maven repository and added it to my pom as dependency with 'provided' scope. I have also added the package X from Bundle B where class A is residing to my pom with Dynamic-import in my pom.xml. One thing to note here - the package X is NOT exported from Bundle B, but i know it can still work, i've seen colleagues do it , but i am not that good yet.

Anyway how i am trying to get instance of the class below :

Bundle bundle;
Class<?> checkClass=bundle.loadClass("full path to class A");

TypeOfClassA newClass=checkClass.newInstance();

and here i am getting :

java.lang.ClassNotFoundException ClassA not found by myapplication
at 

org.apache.felix.framework.BundleWiringImpl.findClassOrResourceByDelegation(BundleWiringImpl.java:1532) at

org.apache.felix.framework.BundleWiringImpl.access$400(BundleWiringImpl.java:75)

But why ? I have the jar loaded, i am using the bundle classloader, also if i cast checkClass to Object, i can see the methods and fields of Class A , so looks good, how can i get an instance of class A ?

Christian Schneider :

In OSGi there is a difference between compile time and runtime. At compile time you see the classes of your own jar and all dependencies from maven.

At runtime a bundle by default only sees its own classes. Any other packages need an Import-Package statement in the Manifest. Normally this is automatically created by bnd when you use a class. Whenever possible you should rely on that automatism.

Your case is different of course as the package you want to access is not exported by bundle B. In this case there is no way to reach class A via the bundle classloader of your own bundle.

Instead you need to use the bundle classloader of bundle B. You can get bundle B for example from the BundleContext. Then you can load the class.

Another option is that you use an exported class C from Bundle B and use the classloader of class C to load class A.

In any case this is a hack. You should avoid to use private classes of another bundle.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=309327&siteId=1