> First, I create a new ClassLoader cl1, more precisely, an instance of
> the subclass MyDomainLoader of ClassLoader. Next, I create an instance
[quoted text clipped - 4 lines]
> the class loader this.getClass().getClassLoader() and _not_ with the
> new class loader cl1 that I provided.
You might find java.net.URLClassLoader a ready made solution (with
file:// URLs).
> final class MyDomainLoader extends ClassLoader
> {
> public MyDomainLoader()
> {
> super();
The no-args ClassLoader constructor uses the system class-loader as a
parent, that is to say the class-loader that (probably) loaded your
application.
Class-loaders typically delegate to their parent before trying to find
the class themselves. So if the class name is available to you
application, the child class-loader wont even attempt to find the class.
You haven't overridden any methods to supply further classes, so no
classes at all can be created belonging to this class-loader.
> }
> }
Tom Hawtin

Signature
Unemployed English Java programmer
http://jroller.com/page/tackline/
oulan bator - 27 Jan 2006 19:30 GMT
the problem is that you MUST load the class through your ClassLoader
Class domainClass1 = null;
try
{
domainClass1 = cl1.loadClass("MyClass");
}
catch(Exception e)
{
throw(new PPException(INTERNAL_ERROR, e.toString())); //
never happens
}
AND that in your class loader you must NOT look in the parent (because
then it is the first class that is loaded)
Try with two classes with the same name one called A that outputs "A"
and one called that outputs "B". If A is in the system classpath, your
classloader will always load it, and you won't manage outputing B.
but if you slighly modify your classloader, so that it won't look in
the parent (see the findclass method details) , then you can have both
A, and B that work together.
I've had the same problem, and I've manage doing it. So you can feel
confident, we gonna make it !
Thomas Hawtin - 27 Jan 2006 19:46 GMT
> the problem is that you MUST load the class through your ClassLoader
The original poster used the long form of Class.forName to achieve that.
> AND that in your class loader you must NOT look in the parent (because
> then it is the first class that is loaded)
Or it uses a parent without the the class already present. For instance,
by using the other ClassLoader constructor.
Tom Hawtin

Signature
Unemployed English Java programmer
http://jroller.com/page/tackline/
oulan bator - 27 Jan 2006 19:58 GMT
you're right I saw it too late... but it doesn't change the second
argument
thanks for correcting me...
Ulrich Scholz - 28 Jan 2006 09:22 GMT
| but if you slighly modify your classloader, so that it won't look in
| the parent (see the findclass method details) , then you can have both
| A, and B that work together.
Yes, I thought of that, too, but I cannot find a solution by myself.
Could you give me a short example / some more hints how such a modified
classloader might look like.
Thank you,
Ulrich
oulan bator - 28 Jan 2006 10:12 GMT
up the thread later mondeay for instance, I have all the material at
work ...
just look deeply in the javadoc of findClass method :
"Finds the class with the specified binary name. This method should be
overridden by class loader implementations that follow the delegation
model for loading classes, and will be invoked by the loadClass method
after checking the parent class loader for the requested class. The
default implementation throws a ClassNotFoundException."
it's your job NOT to check parent class loader AND
override the loadClass(String name) method so that it calls the
protected Class<?> loadClass(String name, boolean resolve)
with resolve=false !
and that's it
with resolve = true (s
Ulrich Scholz - 30 Jan 2006 11:39 GMT
Sorry, but I still haven't found a soltion. I did as you suggested.
Below, you find my new class MyClassLoader. But I still don't with what
to overwrite findClass(name), the original implementation simply throws
an exception. How can I find a class "myself"? Do I really have to
load it myself and then use defineClass?
Thanks, Ulrich
final class MyDomainLoader extends ClassLoader
{
public MyDomainLoader()
{
super();
}
protected Class<?> loadClass(String name, boolean resolve)
throws ClassNotFoundException
{
return findClass(name);
}
public Class<?> loadClass(String name) throws
ClassNotFoundException
{
return loadClass(name, false);
}
}
oulan bator - 31 Jan 2006 17:54 GMT
sory I was out of the office today.
- but the rule is that you cannot have your classes in the classpath
(otherwise their gonna be found by the parent).
- in the findClass you MUST look for the bytes by yourself (usually
this is what you really want to do). then call the define class.
- resolve depends on what you want to do: if you want that your class
can be seen from the others classloaders, you must call it with
resolve=true, otherwise (usually for a component) you don't want to
share the class (only instances), the you must call it with
resolve=false (as you did)
tommorrow I'll copy paste a piece of code that works
Ulrich Scholz - 02 Feb 2006 13:21 GMT
Thank you, code would be perfect - I almost get grey hair
Uli
oulan bator - 07 Feb 2006 16:07 GMT
/** returns a Class corresponding to the class name. load
* the class with the corresponding byte[] in the MetaComponent.
* @param name the name of the Class
* @author
* @date 4 \ 4 \ 2000
*/
protected Class findClass(String name) throws ClassNotFoundException
{
//System.out.println("finding class in component "+name);
byte[] b=getBytes(classNameToEntry(name) ); //due to zip lookup
//getBytes does the specific par to look for the bytes
if (b==null) throw new ClassNotFoundException("No Class File
found.");//return null;
log.debug("[Loaded "+name+" from Component]");
return defineClass(name, b, 0, b.length);
}
here is the body of my findClass method