• Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Classloader issues

 
Stan James
(instanceof Sidekick)
Ranch Hand
Posts: 8791
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
(When it works) I have the ability to specify plug in classes in configuration. In configuration I set one or more extra classpath entries and one or more classnames to load. At startup I make a new URLClassLoader and add the classpath entries and the plugin classes load fine.

Later on the plugin classes reference other classes in Fit whicih in turn references other classes in the same plugin directory and I get class not found errors. I added some debugging to the plugin class to get the classloader that loaded it and display the URLs and the ones I need are still there.

Shouldn't anything I instantiate from an object inherit the classloader that loaded the object? I'm expecting that to pass the extra plugin directory to Fit and then back to my own classes. Any idea why it's not doing it?
 
Ernest Friedman-Hill
author and iconoclast
Marshal
Pie
Posts: 24212
35
Chrome Eclipse IDE Mac OS X
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Does your classloader load Fit, or is it loaded by the application classloader? If so, then Fit may well use its own classloader to try to load plugin classes.

This is really tricky stuff -- something I had to work out myself (with help from Ted Neward) for Jess. I've never looked at the source for Fit; have you rooted around and found the code where it loads classes by name? Does it just blindly use Class.forName() ?
 
Stan James
(instanceof Sidekick)
Ranch Hand
Posts: 8791
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I was afraid Fit might be doing it's own loading. I'm sure it's doing Class.forName() or something very similar for the fixtures ... not many other ways to load em. I really just want to update the classpath and send the rest of the system on its way so it can do new or class.forname or whatever it wants. Don't the servlet and ejb containers do that for me?

I ran across an article about setting Thread.currentThread.setContextClassLoader but that seems to be worse, not better.
 
Ernest Friedman-Hill
author and iconoclast
Marshal
Pie
Posts: 24212
35
Chrome Eclipse IDE Mac OS X
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Stan James:
... not many other ways to load em.


Well, there are two ways: using Class.forName(String) (which uses the ClassLoader that loaded the class in which the call appears), and using Class.forName(String, boolean, ClassLoader), where you can specify the ClassLoader to use. A lot of code doesn't do this, even though it should. As I said, my guess is that Fit isn't doing it, so the ClassLoader that loaded Fit is turning around and trying to load classes from your plugin, and not finding them. If Fit instead used your loader, you wouldn't have this problem.

Read Ted Neward's seminal paper on this; it's very well done and it's really pretty simple once you understand it. Then make the necessary mods to Fit, send in the patches, and take credit for it!

Another possible fix, if this works for you, is for your plugin's classloader to be the one to load Fit. If many plugins use Fit, this would have the unfortunate effect of loading multiple copies -- but who knows, this might be tolerable.
 
Stan James
(instanceof Sidekick)
Ranch Hand
Posts: 8791
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Here's what I'm attempting in my Wiki. Configuration allows specification of additional classpaths and two types of Wiki components: commands and macros. "Out of the box" the Wiki knows nothing about Fit.

I put a command that runs Fit and some fixtures in a new project MCFit. This project is what I'm trying to add to the class loader. MCFit already has references to the Fit jar. My hope was that this would work

* Make a URLClassLoader including MCFit/bin/
* Use it to load the command
* The command loads Fit
* Fit loads the fixtures

Here's the thread thing I found and tried. It wouldn't even load the command class!

I'll follow up on the article you linked. Fit only uses class.forName.newInstance() about three times. Something I can mess with for sure.
[ October 24, 2005: Message edited by: Stan James ]
 
Stan James
(instanceof Sidekick)
Ranch Hand
Posts: 8791
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Ok, that worked along with a quick mod to Fit to use a 3-arg class.forName

That was right out of the paper you linked! Thanks!!
[ October 24, 2005: Message edited by: Stan James ]
 
Ernest Friedman-Hill
author and iconoclast
Marshal
Pie
Posts: 24212
35
Chrome Eclipse IDE Mac OS X
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Great!
 
Mr. C Lamont Gilbert
Ranch Hand
Posts: 1170
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Classloader is not associated with instantiation. Its associated with class loading. That occurs when the class is referenced in any way inside of a file. If you have a reference of a type in a file, the classloader will load that type when the class of that file is loaded. It wont wait for an object to be instantiated.

You can set the current classloader into the context classloader. sometimes that works. When you change the context classloader its good practice to change it back right after you call your target method.
 
JuanP barbancho
Ranch Hand
Posts: 52
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi,

You could "hook" Your classloader in the chain of classloader, this is a hole of security.


I attach the source by example:
myLoader is my new loader-
:
 
Stan James
(instanceof Sidekick)
Ranch Hand
Posts: 8791
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi, welcome to the ranch!

I used to use reflection to change visibility of the addURL() method and add my plugin directories. It seemed to break with the latest JDK 5. Rather than figure out what went wrong, I thought I'd try to find a more legitimate way to do this.

BTW: I did post this problem & the thread & context solution to the Fit discussion board and got a reply from someone who had done the same thing and submitted the change for consideration to the Fit Folks.
[ October 25, 2005: Message edited by: Stan James ]
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic