Eclipse as we know is a great implementation of plugin-architecture.
We decouple different components of a system into bundles.
plugin-architecture is very simplistic in nature, highly extensible and modular at the cost of a tricky class-loading policy.
Actually Eclipse is a story of several class-loaders.
It iniataites a chain of class loaders to load the plug-ins lazily as specified in component-specific files.

If we understand its class-loading policy and learn some tricks, then we can make different third-party jars talk to each other and avoid infamous ‘ClassNotFound Exception’.

The immediate parent of a plug-in class loader is the Eclipse Boot Class Loader (providing access to boot.jar). The standard java system class loader is the Grand parent which terminates the chain. So we can see that the Application Class-loader which loads classes from the system’s CLASSPATH is not part of the chain.
That’s why while loading product components, Eclipse does not look into Classpath in contrast to any other java-based client applications.

On start-up, the eclipse platform builds a shadow of all the plugins by reading all the manifest files into a plug-in registry.
Whenever a plugin is started by Eclipse Application Class,
the class-loader for takes-off.

If tries to access any class from another plugin,
Eclipse invokes the Plug-in Class-loader coresponding to

That’s the essence of Eclipse OSGi.

Q1. How to bundle third-party applications inside my product ?
Its of no use to specify third-party jars in classpath.
While building the application com.myProduct, we should bundle all the required jars (viz. log4j, jpox, xstream) in a single plugin (com.myProduct.library) and export the apis so that they are available during runtime.
In this approach, core myProduct apis which are dependent on com.myProduct.library, can only use the required classes (say jpox, xstream etc). But not the vice versa i.e. third-party jars can’t see our product classes (eclipse osgi does not allow circular dependency)

Q2. So how can a third-party jar (log4j.jar) see the classes from during runtime ?
Lets assume plugin logs messages using log4j.
So during runtime, log4j needs to see the classes from plugin
This can be achieved by registering log4j with Eclipse-Buddy Policy and specifying as a buddy of log4j.

# log4j Manifest.MF
Bundle-Name: org.apache.log4j
Bundle-Version: 1.2.13

Eclipse-BuddyPolicy: registered

# myplugin Manifest.MF
Bundle-Version: 1.0.0
Requires-Bundle: org.apache.log4j,…

Eclipse-RegisterBuddy: org.apache.log4j

If anyone registers with log4j as its buddy, and log4j needs to find a class then it will check all the buddies before throwing “ClassNotFound” Exception

Q3. How can users actually hack eclipse configuration files to integrate required jars on-the-fly.
Say user has installed a plugin com.magicScript which allows him to program using any script including jruby. But the product plugin doesn’t ship the jruby jars i.e. does not adopt any of the above mechanisms.
So user have to add JRUBY_MOME in eclipse.ini. Now when eclipse will start up it will set jruby home in the path.
Lets assume the com.magicScript plugin already depends on a plugin com.magicScript.library containing a lib folder.
Next the jruby.jar needs to be placed inside the lib folder and the location lib\jruby.jar needs to be specified in the of com.magicScript.library.

Finally, starting eclipse with -clean option will automatically first set Jruby path and then invoking magicScript perspective will trigger the classLoader for the bundle com.magicScript.library which in turn will load jruby classes from the jar (as specified in

Thus user will be able to code/compile/run jruby.

This same trick can be used if we want the user to dynamically specify a DB driver jar and connect to a db using a plugin already installed in his environment.

Say com.myProduct.dbExplorer plugin will load classes from the jar to be specified by users during runtime.

Q4. What if while running our product we need to access a class which is not loaded by the bundle-classloader ?

So far we depend only on Eclipse Bundle-ClassLoader and we configure eclipse in such a way (either development-time / runtime) that all required jars will be loaded by the classloader of the bundle in which jars are packed.

Now we need to set certain jars in custom classloader so that the classes bundled in the jar can be loaded on demand !
A typical scenario is contains scriptDebugger.jar (some 3rdparty jar) whose api need to be invoked during runtime and the api class will access some class of jruby.jar (may be specified by user during runtime) which can’t be packed inside the product.

//The follwoing piece-of-code should be part of the to load classes from jruby jar that user will specify during runtime.

// gather the names and loacation of jars as provided by user through preference page after product is deployed.
String[] jarslist = DynamicJarLoader.getThirdPartyJars();

URL[] jarURLs = new URL[jarslist.length];
JarFileLoader newLoader = new JarFileLoader(jarURLs);
for (int i = 0; i < jarslist.length; i++) {
newLoader.addFile (jarslist[i]);
class JarFileLoader extends URLClassLoader
public JarFileLoader (URL[] urls)
super (urls);

public void addFile (String path) throws MalformedURLException
String urlPath = “jar:file://” + path + “!/”;
addURL (new URL (urlPath));

Now swap bundleclassloader with your classloader !
ClassLoader currentLoader = Thread.currentThread().getContextClassLoader();
try {
current.setContextClassLoader( newLoader);
// Either Load reqd. classes and work with them
newLoader.loadClass (“org.jruby.JRubyClient”);
newLoader.loadClass (“org.hsqldb.jdbcDriver”);
// Or invoke some other api (of scriptRunner.jar which will load JRuby classes to compile/run jruby script)
}catch(Exception exception) {
}finally { // Restore Eclipse Bundle Class-loader

further reading :