Class for name with context classloader
You may know that the osgi classloading is a bit different as usual. In Equinox there are also Buddies and Fragments which effect the Classloading.
This influences a Class.forName() as well as Class.getResource() (If you need to load a resource also try bundle.getEntry() !). If you load by getSystemResource(), forget about this command! You will not get happy with it. If it’s in a third party plugin try to give them a patch or something like that. If give these suggestions only by the way because you will find a lot about these subjects.
I want to cover the point of loading classes by the context classloader (Thread.currentThread().getContextClassLoader()). The context classloader, as you know, is the classloader assigned to the current thread. The important point is, that this classloader is automatically assigned to the active classloader of the class which has created the thread. Confused? Don’t worry it’s realy simple. Let’s put it in this way; You have a Class ‘Foo’ with a method ‘public void bar()’. In this method a new Thread is created. If this method is called the new thread gets the classloader of class ‘Foo’. Simple, isn’t it?
Going further this context classloader could be the specific classloader of Bundle ‘A’ which contains the class ‘Foo’.
One more ‘Casual’-Thing. We need to load a class in method ‘bar’ by reflection out of our Bundle ‘A’. OK sure you will say ‘That know problem.’ Nevertheless i can put one on top
Bundle ‘B’ registers a listener at bundle ‘A’ and what to call a class of bundle ‘C’ in this listener. Bundle ‘A’ has a ‘Buddy-Policy’. And bundle ‘A’ calls the registered listener in a seperate thread. OK put it into a image (maybe it will say more than these words
)

Image 1
You see the problem? Of course bundle ‘B’ can load a class from bundle ‘C’. But bundle ‘A’ creates a new thread, and bunlde ‘B’ tries to load the class from bundle ‘C’ with the context classloader (for what reason ever!). This context classloader is the classloader of bundle ‘A’ and has no dependecy to bundle ‘C’. Consequently we will get a ClassNotFoundException (or a NoClassDefFound i couldn’t remember).
You will get this solved if you will set the context classloader to a new instance of org.eclipse.core.runtime.internal.adaptor.ContextFinder (give to the constructor the parent classloader) or the classloader of bundle ‘B’. But way better is to try other classloaders (for example your own classloader) to load the class before. Anyhow if you have to load the class by context classloader recognize the risks you will have.
be happy until cancelled,
Your Codescale’s