Organizing classes into a hierarchy.
I have an application where it is critical that I can organize a set of classes into a hierarchy and then load each one in order.
The reason is that I have code similar to this:
try
{
Class clazz = this.defineClass(className,data,0,data.length);
}
catch(Exception e)
{
e.printStackTrace();
}
Say, for example, I have a jar file full of classes, some of which extend each other. (None of these classes are in classpath/have been defined yet).
If I ClassLoader.define() them one by one, in no particular order, I will get exceptions, because some classes will have parent classes/interfaces that I haven't defined yet.
I need to organize them so I can define them, one by one.
Any help with this? I have tried to write a Class Hierarchy class, but I failed.
Thanks.
[1025 byte] By [
AlexZorina] at [2007-10-1 22:57:09]

How about using a Linked List of classes that have failed the define.
1) Start with a linked list of all the classes to be defined.
2) If a class fails the define then put it in another list of failed classes.
3) run to the end of the classes to define list. You will now have an list of all the classes that failed the define. This must be shorter than the original list.
4) Make the new list of failed classes the list to be processed through and create a new empty list of failed classes.
5) Now process your way through the new list of classes to be defined and try to define them. If a class fails the define then put it in the list of faled classes.
Repeat 3), 4) and 5) until the list of failed classes is empty. You should have then defined all your classes.
I'm sure this could be done with recursive calls but I would think what I have specified above will work.
Hello Alex (don't know if you're the same Alex Zorine I happened to work with, let's give it a try :-)
Why do you want to defineClass() each class prior to loadClass() them?
With the usual loadClass() mechanism, the JVM will take care of the load order for you, automatically identifying, and requesting the load of, the required dependencies.
Brgds,
Jerome
No, I'm not Alex Zorine :).
I need to use defineClass(), because I am recieving a stream of encrypted bytes, which when decrypted, end up being the bytes of class files. So the classes are not in my classpath, and loadClass() only works when they are in classpath (e.g are resolveable by name, I assume).
@JimDinosaur, thanks a lot, I'll try that out. :).
OK, your idea worked. However, I have a new problem.
These classes are obfuscated, and defineClass() is throwing exceptions for ClassFormatError on three of the classes:
SEVERE: Error in defenition: java.lang.ClassFormatError: Unknown constant tag 0 in class file client
7/09/2005 11:45:00 jagex.entropy.applet.ClassHier _processErrored
SEVERE: Error in defenition: java.lang.ClassFormatError: Illegal constant pool index 0 for method name in class file OBOSMEDX
7/09/2005 11:45:00 jagex.entropy.applet.ClassHier _processErrored
SEVERE: Error in defenition: java.lang.ClassFormatError: Illegal constant pool index 0 for method name in class file WEVRTBOZ
7/09/2005 11:45:00 jagex.entropy.applet.ClassHier _processErrored
These classes will run, is there any way to make the ClassLoader not verify them?
> No, I'm not Alex Zorine :)
Too bad :-) Well I'll try to help anyway...
> I need to use defineClass(), because I am recieving a
> stream of encrypted bytes, which when decrypted, end
> up being the bytes of class files.
But why do you need to define the classes as soon as you "receive" them?
Why not stuff the decrypted bytes somewhere on disk or in memory, and let your custom classloader load them only when they are required?
> So the classes are not in my classpath, and loadClass() only works when
> they are in classpath (e.g are resolveable by name, I assume).
Not exactly. loadClass(...), called on any class loader, will work as soon as the classloader or one of its parent is able to find the class. The classes in the classpath are indeed loaded by one of the parents class loaders (it used to be called "system class loader"). The others will have to be found out by your classloader's findClass() method.
One last remark: if the encryption of class files is meant to protect the classes against decompilation, it's doomed unless you completely manage the client machine (it may, though, protect you against network sniffing). Obfuscation, on the other hand, may do enough of a job.
You dont need to load them in order. In fact you cant load them in order. Your classpath is whatever your classloader knows about. its not some hard defined thing.
You need to define a classloader such that it is capable of knowing about ALL of your classes at the same time. Its going to try to load the classes it needs as it needs them so they must be available. You do not load the classes, the loader does. no you cant use a class before you define its parent.