Forum Controls
Spotlight Features

The Rich Engineering Heritage Behind Dependency Injection

Andrew McVeigh takes us on a tour of the rich heritage behind dependency injection, what it represents, and tells us why its here to stay.

Java, the OLPC, and community responsibility

The "One Laptop Per Child" project has a great device ready to ship, but there's no Java on there. Let's think about working together to put Java on OLPC!
Replies: 6 - Pages: 1  
Threads: [ Previous | Next ]
  Click to reply to this thread Reply

Resolving ClassLoader issues across plug-ins

At 3:16 AM on Jan 18, 2006, Sanjay Chaudhuri Blooming Javalobby Member wrote:

Scenario 1:
Imagine we have a 3rd party JAR in our application plug-in's lib directory, and necessary CLASSPATH added so that it's classes may be used in our code.Most of these code libraries allow dynamic loading of classes. In order to get that through with Eclipse,most of us are aware of the trick:

Thread currentThread = Thread.currentThread();
ClassLoader oldLoader = currentThread.getContextClassLoader();

try
{
  currentThread.setContextClassLoader( XyzTest.class.getClassLoader());

  //Call the library code
}
...
...
finally
{
  currentThread.setContextClassLoader( oldLoader);
}


Scenario 2:
It is a good practice to have 3rd party library JARs wrapped up in a different plugin, and to make other application plug-ins dependent on that, so that, each of these application plug-ins do not need to have those library files individually added to their classpaths,and duplicate them.

Having said this, let's think of putting the XML parser library, Digester jars from Apache, in a plugin org.xyz.lib . I am not going into the details of how to make 3rd party jars wrapped up in a separate plugin. There are lots of articles on that in this forum, as well as other forums.
We have our application plug-in, say org.xyz.abc , and we make it dependent on org.xyz.lib

Now, let's say we start using the Digester functions. Everything compiles well, but when we try to run the application, we get a run-time error, java.lang.ClassNotFoundException

Putting our old trick in action :

Digester digester = new Digester();
...
...

Thread currentThread = Thread.currentThread();
ClassLoader oldLoader = currentThread.getContextClassLoader();

try
{
  currentThread.setContextClassLoader( XyzTest.class.getClassLoader());
  digester.parse(...);
}
...
...
finally
{
  currentThread.setContextClassLoader(oldLoader);
}

also doesnot seem to help at all, and we get the same error.

Investigating closely, we see that the current scenario is different from the first one. The class loader of the Digester class, is definitely not the same as the class loader of the currently executing application plug-in's class, because Digester is sitting on a different plug-in,and classloaders in eclipse are different for different plug-ins.
Fortunately Digester has 2 public methods:
setUseContextClassLoader(boolean use) and
setClassLoader(java.lang.ClassLoader classLoader)

Either one would make things work:

1. If we wish to use setUseContextClassLoader(boolean use) , then code should look something like this:

Digester digester = new Digester();
...
...

Thread currentThread = Thread.currentThread();
ClassLoader oldLoader = currentThread.getContextClassLoader();

try
{
  currentThread.setContextClassLoader( XyzTest.class.getClassLoader());
  digester.setUseContextClassLoader(true);
  digester.parse(...);
}
...
...
finally
{
  currentThread.setContextClassLoader(oldLoader);
}

2. Using setClassLoader(java.lang.ClassLoader classLoader) , the code would be much smaller, because Digester does the remaining job

Digester digester = new Digester();
...
...

try
{
  digester.setClassLoader( XyzTest.class.getClassLoader());
  digester.parse(...);
}
...
...

Depending on your 3rd party libraries,you need to decide which to use. Now unfortunately, if the 3rd party libraries do not provide similar methods as shown above, and always internally uses a statement like this.getClass().getClassLoader() to obtain the current classloader, then I think we are in trouble and cannot package it in a separate plug-in. Rather we then need to package with individual plugins as was shown for Scenario 1 .
  Click to reply to this thread Reply
1. At 1:13 PM on Jan 18, 2006, Bob Balfe Javalobby Newcomers wrote:

Re: Resolving ClassLoader issues across plug-ins

I think packaging them into their own plugins is the way to go. This forces these 3rd party jars to be packaged correctly for re-use in the Eclipse platform. If an API is exposed in Eclipse it should fit the OSGI bundle model. Going ahead and wrapping it correctly with an Eclipse layer is probably your safest bet if Apache won't wrap it already.
  Click to reply to this thread Reply
2. At 3:06 PM on Jan 18, 2006, Haris Peco DeveloperZone Top 100 wrote:

Re: Resolving ClassLoader issues across plug-ins

this is perfect scenario for buddy classloading
  Click to reply to this thread Reply
3. At 4:47 PM on Jan 18, 2006, Sanjay Chaudhuri Blooming Javalobby Member wrote:

Re: Resolving ClassLoader issues across plug-ins

Thanks for pointing that out. Indeed, in this case, we can use Buddy classloading in eclipse to resolve these classloader issues, by simply adding:
Eclipse-BuddyPolicy: registered
in the MANIFEST.MF of the 3rd party library plug-in
and in the application plugins's MANIFEST.MF, we add:
Eclipse-RegisterBuddy: org.xyz.lib
where org.xyz.lib is the library JAR plugin.
  Click to reply to this thread Reply
4. At 2:32 AM on Mar 3, 2006, Veerabhadra B Javalobby Newcomers wrote:

Re: Resolving ClassLoader issues across plug-ins

Hi,
I tried the scenario two and created a plugin for 3rd part jars, now i have my application plugin dependent on the 3rd party jar, but when i try to access the classes of the third party jar..i still get the class not found exception..
am i missing on something??
  Click to reply to this thread Reply
5. At 12:18 AM on Mar 4, 2006, Sanjay Chaudhuri Blooming Javalobby Member wrote:

Re: Resolving ClassLoader issues across plug-ins

As mentioned, if your current 3rd party class, is not having a way to manipulate your current Class-Loader, then these will not work. In that case, Buddy-classloading should do the job. Please look at my previous thread.

Incase you still have a problem, you can send me your proto plugin code with your 3rd party JAR, at account4sanjay AT yahoo dot com, I shall be more than happy to help you.

Thanks

Sanjay
  Click to reply to this thread Reply
6. At 2:44 PM on Sep 20, 2007, Kate Javalobby Newcomers wrote:

Re: Resolving ClassLoader issues across plug-ins

My eclipse debugger is extremely slow. When I hit a break point it takes a very long time to display the variables, and to step over/into code.

I tried to update my eclipse.ini file to different properties, currently it's at:

-vmargs
-Xms1024m
-Xmx1024m
-Xmn256m
--launcher.XXMaxPermSize
512M
--launcher.XXMaxPermSize
128M


The problem doesn't go away. Outside of debug mode, eclipse works fairly fast. Does anyone have any idea of how to fix this problem?

Thank you very much in advance for your help

thread.rss_message