• Post Reply Bookmark Topic Watch Topic
  • New Topic

Loading Classes in at Runtime - NoClassDefFound  RSS feed

 
Will Farquharson
Greenhorn
Posts: 20
IntelliJ IDE Java Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hello,

I'm writing a piece of software that includes a Swing Application that clients will use to connect to a Web App running on Glassfish via Web Services.

Basically, clients will write java classes implementing my interface (AlgorithmInterface), and browse to the class files from the Swing App. They can then choose a problem class to run against - these are ".class" files stored on the server.

Values would then be passed back and forth between the classes using web services:
AlgorithmInterface class <--> Web Service <--> ProblemInterface Class

I have written a subclass of ClassLoader to help load in classes at run time - it can take the directory the user specified, find all the ".class" files, and filter them for ones that implement "AlgorithmInterface".

I thought I could just re-use this code on the server side, so that it could dynamically load in classes that implement ProblemInterface (as opposed to AlgorithmInterface on the client). However, when trying to load a class, the exception "NoClassDefFound" is thrown, and then the name of my interface. Apparently its not finding ProblemInterface.

Is what I'm trying to do impossible on an application server? Maybe it handles ClassLoader differently? It looks like it has no idea what ProblemInterface is. I've tried putting it in the lib/classes folder, importing it in classes and stuff, but no luck.

Sorry about the long-winded post, I tried to be as brief as possible but it's a fairly niggly problem! If anyone could offer any words of advice it would help me in a huuuuuge way!

Thanks!
 
Sri Anand
Ranch Hand
Posts: 392
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
you need to have no argument constructor, for loading class dynamically using class loader.
class.forName("MyClass")

check if you have a no arg constructor
[ December 02, 2008: Message edited by: Sri Anand ]
 
Will Farquharson
Greenhorn
Posts: 20
IntelliJ IDE Java Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
In my custom classloader? It has no constructor, so I suppose that just defaults to a no-arg one. It works fine on everything except running it on an application server.

I think I need to be getting hold of the application server's classloader using Thread.getContextClassLoader() - however, this means I can't use my own custom classloader.

There are examples such as this:

http://www.exampledepot.com/egs/java.lang/LoadClass.html

If that worked, it would do exactly what I want to do - but I can't use URLClassLoader; I believe I need to use "Thread.getContextClassLoader()". This is where I get stuck
 
Sri Anand
Ranch Hand
Posts: 392
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I remember i encountered class loading problem using class loader I wanted to load class MyClass , MyClass needed to have a explicitly defined no arg Constructor then it worked
 
Will Farquharson
Greenhorn
Posts: 20
IntelliJ IDE Java Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks very much for the suggestion, but the class it can't find is the interface which can't have a constructor.

The code works fine client-side, and is able to load classes for me and tell me if they implement AlgorithmInterface or not.

However, the code on the sever side which tells me whether or not a class implements ProblemInterface (exact same as client side code), will crash with "NoClassDefFound ProblemInterface". This happens when I call defineClass() in my custom ClassLoader, passing in a byte[] array representing a class that implements ProblemInterface.

I'm sure I must need to do an extra step to get this working on an application server, but what that is I have no idea!

Any more suggestions would be most welcome
 
Carey Evans
Ranch Hand
Posts: 225
Debian Eclipse IDE Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Your custom class loader needs to be able to find ProblemInterface via its parent class loader, or via its own findClass() method. I suspect you�re not passing a parent class loader to the ClassLoader constructor, so the parent will be the system class loader. This works on the client because the system classloader is initialised from the CLASSPATH environment variable or the -classpath (or -cp) option.

I think it will be enough on both client and server for your class loader to use its own class loader as its parent; i.e.It might be better if you pass it in:then:
 
Will Farquharson
Greenhorn
Posts: 20
IntelliJ IDE Java Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
It woooooorked! YUSSS, I was SO stressed out about that! You explained it well, I understand now why it wasn't working. You find yourself in Scotland any time soon I'm owe you a beer, big time.

Thanks for the replies folks
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!