gbadev.org forum archive

This is a read-only mirror of the content originally found on forum.gbadev.org (now offline), salvaged from Wayback machine copies. A new forum can be found here.

OffTopic > Java: Load a class from random path

#129640 - Mr Snowflake - Thu May 24, 2007 3:04 pm

Hi,

How can I load a class, which sits in a package, when I only know the path and filename of that class? If I use a URLClassLoader I can put the path into the ClassLoader but then I can't load the class because I don't know it's package.
_________________
http://www.mrsnowflake.be

#129712 - gauauu - Fri May 25, 2007 2:38 pm

Is it sitting in any sort of package-related directory structure at all (as in, it's in one, but you aren't sure the root of the the package)? Then you can try to write something that uses guesses work, guessing different roots, and trying different package names from that.

If not, then it's gonna be tough. For a one-time case, you can probably grab a java decompiler and find out what package it is, but I don't know for the general case if it needs to be done in code.

#129714 - naleksiev - Fri May 25, 2007 3:13 pm

I can think about one solution. You can read the actual data in the class file so you can find what is the package. I'm sure there must be a ClassReader lib that will do this for you. Probably it's even in the J2SE standard package.

In case you want to do it yourself.
The way it should work is reading just the the ClassFile structure. There are some important things you need to have not parsing the whole structure. You need to load the constant_pool and the super_class offset in the pool. And in the constant_pool[super_class] you will have the full name of the class (package + classname).

You can take a look at http://java.sun.com/docs/books/jvms/second_edition/html/ClassFile.doc.html for more info.

Good luck.

#129716 - ps2aich - Fri May 25, 2007 3:41 pm

Mr Snowflake wrote:
Hi,

How can I load a class, which sits in a package, when I only know the path and filename of that class? If I use a URLClassLoader I can put the path into the ClassLoader but then I can't load the class because I don't know it's package.


I think we had an similar issue in an older thread already (iterating through jar)


Can you give a more concrete example to have an idea what you want to do?

#129816 - Mr Snowflake - Sun May 27, 2007 4:17 pm

ps2aich wrote:
I think we had an similar issue in an older thread already (iterating through jar)
That older threat is mine ;).

ps2aich wrote:
Can you give a more concrete example to have an idea what you want to do?
It's kinda what gauauu said. I know it's position on the disk (path name + file name). And I can assume it's inside the appropriate package dir, but I don't know its fullyquallyfied classname and I also don't know the base dir of the package.

Making a reader myself would work, but I don't have that much time...
_________________
http://www.mrsnowflake.be

#129830 - ps2aich - Sun May 27, 2007 8:12 pm

Mr Snowflake wrote:
ps2aich wrote:
I think we had an similar issue in an older thread already (iterating through jar)
That older threat is mine ;).



Yes I know :-)

In theory, its only a substring problem:

Your path is like:
Code:
/dir1/dir2/dir3/.../dirN/ClassX.java

Your package is like:
Code:
dirN-x.dirN-(x-1).dirN-(x-2)....dirN


So, if you convert your path into package like format, and iterate
through the jar package (with JarFile) and build fully qualified package names,
you have to compare the fully qualified package name with
String.endsWith to find the package, and then search the class
in this package.

#130254 - Mr Snowflake - Fri Jun 01, 2007 3:48 pm

That was also mine solution, but I do not believe the assistant at uni was very pleased with this. He said I should look deeper in the ClassLoader... He could be right, but I don't have that much time left anymore, so I'll go with the string solution :).
_________________
http://www.mrsnowflake.be

#130256 - ps2aich - Fri Jun 01, 2007 4:21 pm

Mr Snowflake wrote:
That was also mine solution, but I do not believe the assistant at uni was very pleased with this. He said I should look deeper in the ClassLoader... He could be right, but I don't have that much time left anymore, so I'll go with the string solution :).


I don't think a standard classloader can do this, since classloading
is done lazy (on demand) and the classloader never iterates over
the jar to look for all classes in there.

But what you can perhaps try is to make your own class loader
that derives from URLClassloader and override the findClass-
Method and refactor the string matching algorithm to be implemented
in this findClass-Method. Then you have to convert the slashes
in the path into dots '.', and you can try a brute force finding of the
class: instead of iterating through the jar, you simple
do a 'super.findClass("x.y.z")' with all substrings by cutting leading
portions of the complete path. Not very efficient, but effectiv.

Example:
Filename is "/x/y/z/a.class" or "C:\x\y\z\a.class".
Convert it to: "x.y.z.a"
Give this to your Classloader with loadClass("x.y.z.a")
In the findClass implementation, you start with
'super.findClass("x.y.z.a")'. If a class is found, we are finished.
If not, you do 'super.findClass("y.z.a"), and so on, until you find the
class or the string is empty.
What I don't know is, wheater the next loadClass does this again,
or if the classloader is intelligent enough to remember that
you have found the class with loadClass("x.y.z.a").

And of course, the solution is not 'clean' in the sense of that
there can exist other classes in the parent classloader (usually
the System class loader), that really have the fully qualified
name "x.y.z.a". In that case, you will retrieve this class,
because the parent is always asked first (security reason, otherwise
you could replace bootstrap/rt-classes, and this is a security hole).

#130596 - Mr Snowflake - Tue Jun 05, 2007 6:38 pm

I've implemented it, and it seems to work ok now (not using my own implementation of urlclassloader, but doesn't matter). The only problem now is that I can load, probably all classes there are, but, funny thing, not java.lang.Class.... really strange.. But i'll just throw an if test inside the code and mention it in the report, so they know, I know the problem exists, but I didn't have enough time to fix it...

Thanks all.
_________________
http://www.mrsnowflake.be

#130666 - ps2aich - Wed Jun 06, 2007 9:18 am

Mr Snowflake wrote:
I've implemented it, and it seems to work ok now (not using my own implementation of urlclassloader, but doesn't matter). The only problem now is that I can load, probably all classes there are, but, funny thing, not java.lang.Class.... really strange.. But i'll just throw an if test inside the code and mention it in the report, so they know, I know the problem exists, but I didn't have enough time to fix it...

Thanks all.


I think java.lang.Class is bootstraped in Java, since its a 'Meta' model of java , that means the Classloader returns your class,
and this is a 'java.lang.Class', so it must be known to the classloader.
Of cource, 'java.lang.Class' itself is a 'java.lang.Class'. I think it is normal that a Class.forName("java.lang.Class") does not make any sense.

Btw, I'm just curious: what kind of project/exercise/task is this you are working on?

#132233 - Mr Snowflake - Sun Jun 24, 2007 10:26 pm

ps2aich wrote:
I think it is normal that a Class.forName("java.lang.Class") does not make any sense.
It's a very correct statement to do Class.forName("java.lang.Class"), the problem with my code was I was filtering the extention .class but apparently i checked if the last 5 chars equalled 'class' so java.lang.Class would become java.lang, which is, obviously, a package ;).

ps2aich wrote:
Btw, I'm just curious: what kind of project/exercise/task is this you are working on?
We were working on a Java class browser with only access to the byte code of the java classes. We needed to genereate html pages with all members of the given classes.
_________________
http://www.mrsnowflake.be