Go Back   Velocity Reviews > Newsgroups > Java
User Name
Password
Register FAQ Members List Calendar Search Today's Posts Mark Forums Read

Reply

Java - Reflection - Class Loading and NoClassDefFoundError

 
Thread Tools Search this Thread
Old 07-24-2006, 03:05 PM   #1
Default Reflection - Class Loading and NoClassDefFoundError


Hi all,

I hope this isn't too obvious a question - I cannot find an answer
anywhere.

I have some classes I need to load using reflection. These classes
are generated and compiled at runtime by my app, so the only info I
have about them is their location. I therefore get a list of the
filenames, and loop through these using a URLClassLoader to load
them in.

However, I am obtaining a NoClassDefFoundError due to the
dependancies between classes. For instance, say we have (interface)
ClassA, and ClassB. ClassB implements ClassA.

No matter which order I load these, I get the NoClassDefFoundError
when loading ClassB. I really don't want to have to try to force
these classes to be on the classpath - that wouldn't work anyway as
when they are generated, they are in their package directory
structure. They have to be loaded straight after creation and their
complilation, so I cannot restart my app either.

Can anyone assist me with this?

Many thanks

Lee.



lee@datadialogs.com
  Reply With Quote
Old 07-24-2006, 07:21 PM   #2
spamBucket@agile-it.com
 
Posts: n/a
Default Re: Reflection - Class Loading and NoClassDefFoundError
Lee,

Are you loading them through the same class loader?

Or are you consing up a new URLClassLoader for each new file?

In general the latter won't work.

/jim g



spamBucket@agile-it.com
  Reply With Quote
Old 07-25-2006, 09:40 AM   #3
Lee
 
Posts: n/a
Default Re: Reflection - Class Loading and NoClassDefFoundError
Hi,

I've tried both - my initial implementation was to use the same
URLClassLoader for all the files. This failed, so I switched to
creating a new ClassLoader each time, passing in the ClassLoader from
the previously loaded class as the parent each time. This has no
apparent effect!

Code Snippet (simplified to just show 2 classes being loaded)

File file = new File("C:\\");

try
{
// Convert File to a URL
URL url = file.toURL();

URL[] urls = new URL[]{url};

// Create a new class loader with the directory
ClassLoader cl = new URLClassLoader(urls);

Class cls = cl.loadClass("classname1");
ClassLoader parentLoader = cls.getClassLoader();
URLClassLoader cl2 = new URLClassLoader(new URL[]{file.toURL()},
parentLoader);

Class cls1 = cl2.loadClass("classname2");

}

Whether I use cl or cl2 to load classname2, I get the same error -
classname2 implements classname1 and I get NoClassDefFoundError.

ta

Lee.

wrote:
> Lee,
>
> Are you loading them through the same class loader?
>
> Or are you consing up a new URLClassLoader for each new file?
>
> In general the latter won't work.
>
> /jim g




Lee
  Reply With Quote
Old 07-25-2006, 10:04 AM   #4
Chris Uppal
 
Posts: n/a
Default Re: Reflection - Class Loading and NoClassDefFoundError
Lee wrote:

> ClassLoader cl = new URLClassLoader(urls);
> Class cls = cl.loadClass("classname1");
> ClassLoader parentLoader = cls.getClassLoader();
> URLClassLoader cl2 = new URLClassLoader(new URL[]{file.toURL()},
> parentLoader);


I don't understand what/why you are doing with the parent classloader here --
it doesn't make any sense at all at first glance. What you should be doing is:

Create a classloader, probably an instance of URLClassLoader. You shouldn't
specify a parent unless you /yourself/ want to build a tree of classloaders
(which sounds unlikely for this application). It should be configured so that
all the classfiles you are interested in are on its own "classpath".

The use it to load classes. It is, as far as I know, a mistake to call the
URLClassloader's loadClass() directly (in fact it's impossible, so your sample
code must not be very representative of what you are really doing). You should
always use Class.forName().

URL urls = ...
Classloader loader = new URLClassLoader(urls);
Class cl1 = Class.findClass("class1", true, loader);
Class cl2 = Class.findClass("class2", true, loader);

Simple as that...

Incidentally, if code in class1 or class2 uses Class.forName(String) -- i.e.
the single argument form -- then that will automatically use the custom
URLClassLoader. You only need to specify the classloader explicitly in code
which was not loaded via that classloader.

-- chris




Chris Uppal
  Reply With Quote
Old 07-25-2006, 11:53 AM   #5
Lee
 
Posts: n/a
Default Re: Reflection - Class Loading and NoClassDefFoundError
Chris,

Thanks for your input. The reason that I implemented code using a
parent classloader is that's what half the websites on this subject
suggested doing! I initially implemented this in the much simpler form
you suggested, although I was using LoadClass as illustrated in my
snippet. I don't know why you think it's impossible to use LoadClass
directly - the code snippet I gave you was taken directly from my code,
with variable names changed to protect the innocent. It works
perfectly providing that I'm not attempting to load a class that
implements another.

I will now go and try your snippet, to see if it helps. Thanks again
and watch this space!

Lee.




Chris Uppal wrote:
> Lee wrote:
>
> > ClassLoader cl = new URLClassLoader(urls);
> > Class cls = cl.loadClass("classname1");
> > ClassLoader parentLoader = cls.getClassLoader();
> > URLClassLoader cl2 = new URLClassLoader(new URL[]{file.toURL()},
> > parentLoader);

>
> I don't understand what/why you are doing with the parent classloader here --
> it doesn't make any sense at all at first glance. What you should be doing is:
>
> Create a classloader, probably an instance of URLClassLoader. You shouldn't
> specify a parent unless you /yourself/ want to build a tree of classloaders
> (which sounds unlikely for this application). It should be configured so that
> all the classfiles you are interested in are on its own "classpath".
>
> The use it to load classes. It is, as far as I know, a mistake to call the
> URLClassloader's loadClass() directly (in fact it's impossible, so your sample
> code must not be very representative of what you are really doing). You should
> always use Class.forName().
>
> URL urls = ...
> Classloader loader = new URLClassLoader(urls);
> Class cl1 = Class.findClass("class1", true, loader);
> Class cl2 = Class.findClass("class2", true, loader);
>
> Simple as that...
>
> Incidentally, if code in class1 or class2 uses Class.forName(String) -- i.e.
> the single argument form -- then that will automatically use the custom
> URLClassLoader. You only need to specify the classloader explicitly in code
> which was not loaded via that classloader.
>
> -- chris




Lee
  Reply With Quote
Old 07-25-2006, 12:02 PM   #6
Lee
 
Posts: n/a
Default Re: Reflection - Class Loading and NoClassDefFoundError
Hi, just to clarify - when you say findClass, I'm assuming you mean
forName?


Lee wrote:
> Chris,
>
> Thanks for your input. The reason that I implemented code using a
> parent classloader is that's what half the websites on this subject
> suggested doing! I initially implemented this in the much simpler form
> you suggested, although I was using LoadClass as illustrated in my
> snippet. I don't know why you think it's impossible to use LoadClass
> directly - the code snippet I gave you was taken directly from my code,
> with variable names changed to protect the innocent. It works
> perfectly providing that I'm not attempting to load a class that
> implements another.
>
> I will now go and try your snippet, to see if it helps. Thanks again
> and watch this space!
>
> Lee.
>
>
>
>
> Chris Uppal wrote:
> > Lee wrote:
> >
> > > ClassLoader cl = new URLClassLoader(urls);
> > > Class cls = cl.loadClass("classname1");
> > > ClassLoader parentLoader = cls.getClassLoader();
> > > URLClassLoader cl2 = new URLClassLoader(new URL[]{file.toURL()},
> > > parentLoader);

> >
> > I don't understand what/why you are doing with the parent classloader here --
> > it doesn't make any sense at all at first glance. What you should be doing is:
> >
> > Create a classloader, probably an instance of URLClassLoader. You shouldn't
> > specify a parent unless you /yourself/ want to build a tree of classloaders
> > (which sounds unlikely for this application). It should be configured so that
> > all the classfiles you are interested in are on its own "classpath".
> >
> > The use it to load classes. It is, as far as I know, a mistake to call the
> > URLClassloader's loadClass() directly (in fact it's impossible, so your sample
> > code must not be very representative of what you are really doing). You should
> > always use Class.forName().
> >
> > URL urls = ...
> > Classloader loader = new URLClassLoader(urls);
> > Class cl1 = Class.findClass("class1", true, loader);
> > Class cl2 = Class.findClass("class2", true, loader);
> >
> > Simple as that...
> >
> > Incidentally, if code in class1 or class2 uses Class.forName(String) -- i.e.
> > the single argument form -- then that will automatically use the custom
> > URLClassLoader. You only need to specify the classloader explicitly in code
> > which was not loaded via that classloader.
> >
> > -- chris




Lee
  Reply With Quote
Old 07-25-2006, 12:33 PM   #7
Lee
 
Posts: n/a
Default Re: Reflection - Class Loading and NoClassDefFoundError
Ok, I've had another look through your comments, and I'm a touch
confused.

findClass, as a member of Class, is a protected method and therefore I
can't call it unless I override it. Also, it's a single argument only,
I can't find anything that matches what you have illustrated.

I can use forName but the code is not inside Class1 or Class2.
Therefore it doesn't work on the second (implementing class). Also, I
have to set the initialise boolean parameter to false or it fails for
all files.

I also note that you mention something about having these files on the
classpath. These files will be generated at runtime, and put into a
dynamically specified directory. Therefore I cannot add this directory
to the classpath.

Cheers again.

Lee.



Lee
  Reply With Quote
Old 07-25-2006, 02:14 PM   #8
Chris Uppal
 
Posts: n/a
Default Re: Reflection - Class Loading and NoClassDefFoundError
Lee wrote:

> Ok, I've had another look through your comments, and I'm a touch
> confused.


My mistake. I meant Class.forName() wherever I mentioned Class.findClass() (I
find Class.forName() a very unintuitive name, and keep substituting a "clearer"
one automatically). My apologies for the confusion.


[from an earlier post]

> I don't know why you think it's impossible to use LoadClass
> directly - the code snippet I gave you was taken directly from my code,
> with variable names changed to protect the innocent.


Again, my mistake -- I was thinking of ClassLoader.findClass() (notice a
pattern here ? .

However, loadClass() is only public in one form (which incidentally, is /not/
the form used as an example in the JavaDoc...) and its other forms (including
its "replacement" findClass()) are documented as intended only for the JVM to
call, or for classloaders to delegate to their superclass implementations. I'm
not sure why loadClass(String) is public. One indication that it probably
shouldn't be is that it doesn't work for loading array classes. I believe that
we are better off avoiding even the public form. YMMV.


[back to the most recent post]

> I also note that you mention something about having these files on the
> classpath. These files will be generated at runtime, and put into a
> dynamically specified directory. Therefore I cannot add this directory
> to the classpath.


I did put the word "classpath" into scare quotes -- to show that I didn't mean
the /real/ classpath. All I meant was the classpath-like sequence of URLs that
each URLClassLoader is configured to search.

-- chris




Chris Uppal
  Reply With Quote
Old 07-25-2006, 02:33 PM   #9
Lee
 
Posts: n/a
Default Re: Reflection - Class Loading and NoClassDefFoundError

> My mistake. I meant Class.forName() wherever I mentioned Class.findClass() (I
> find Class.forName() a very unintuitive name, and keep substituting a "clearer"
> one automatically). My apologies for the confusion.

No worries, I appreciate your assistance!

> However, loadClass() is only public in one form (which incidentally, is /not/
> the form used as an example in the JavaDoc...) and its other forms (including
> its "replacement" findClass()) are documented as intended only for the JVM to
> call, or for classloaders to delegate to their superclass implementations. I'm
> not sure why loadClass(String) is public. One indication that it probably
> shouldn't be is that it doesn't work for loading array classes. I believe that
> we are better off avoiding even the public form. YMMV.

You are probably right, as I can't get it to work!

> I did put the word "classpath" into scare quotes -- to show that I didn't mean
> the /real/ classpath. All I meant was the classpath-like sequence of URLs that
> each URLClassLoader is configured to search.

~ Aha, right you are then, I did worry for a minute!

I still can't get it to work though, even with your suggestions! I
have a fudgy way to work round the problem at the moment but if you or
anyone has any further suggestions I;d be really grateful.

Cheers Chris and other poster,

Lee.



Lee
  Reply With Quote
Old 07-26-2006, 08:32 AM   #10
Chris Uppal
 
Posts: n/a
Default Re: Reflection - Class Loading and NoClassDefFoundError
Lee wrote:

> I still can't get it to work though, even with your suggestions! I
> have a fudgy way to work round the problem at the moment but if you or
> anyone has any further suggestions I;d be really grateful.


If you can describe how your "fudge" differs from the obvious way of doing
this, then it might be possible to guess why the obvious way isn't working.

-- chris




Chris Uppal
  Reply With Quote
Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are Off
Pingbacks are Off
Refbacks are Off

Similar Threads
Thread Thread Starter Forum Replies Last Post
Loading jars for Java Web Start nhdsl Software 0 06-17-2009 02:21 PM
loading java class from .war file jayeth Software 0 04-09-2009 07:06 PM
Loading 24,000 rows into C# .net Datagrid Kagu Software 0 03-10-2009 06:51 PM
Custom Class Loader for Web Application using Tomcat tapas.adhikary Software 0 04-22-2008 09:53 AM
Error loading Explorer.exe Jeff Shealey A+ Certification 0 06-23-2003 01:14 AM




SEO by vBSEO 3.3.2 ©2009, Crawlability, Inc.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46