# ClassLoader



## hpa42 (8. Nov 2005)

Hi

Schreibe zurzeit meinen eigenen Klassenbrowser mit einem eigenen ClassLoader. Jetzt habe
ich Problem beim automatischen Laden von .class Files vom lokalen Filesystem.

Situation:
- Ich habe einen FileBrowser geschrieben, welcher alle Java .class Files sucht.  Die gefundenen 
.class Files sollen geladen werden um Attribute und Methoden aufzulisten. Package Namen, CLASSPATH, ..., sind natürlich so nicht bekannt, nur das aktuelle Directory mit dem File eg. ExecDemo.class.

Fragen:
- Wie kann ich ein beliebiges .class Files aus einem aktuellen Directory lesen und laden, ohne den Package-Namen zu kennen. Geht das gar nicht? Wenn doch wie?

- Brauche ich den ClassLoader oder besser den URLClassLoader.


kind regards /hp

Dieser Code funktioniert, aber eben nicht dynamisch. 


```
File classPath = new File("D:\\eclipse\\workspace\\MVC recoded\\classes");
                    URL  url;
                    URL[]urls;
                    URLClassLoader urlClassLoader;
                    Class          testLoadedClass, lc;
                    Method         methods[];
                    try
                    {
                        url  = classPath.toURL();
                        urls = new URL[]{url};
                        urlClassLoader  = new URLClassLoader(urls);
                        testLoadedClass = urlClassLoader.loadClass("examples.ExecDemo");
                        methods         = testLoadedClass.getMethods();
                        System.out.println(testLoadedClass.getName());
                        System.out.println("   # " + methods[0].toString());                      
                        lc = testLoadedClass.getClass();
                    }
                    catch(Exception  ex)
                    {
                        System.out.println("Exception: " + ex);
                    }
```


----------



## Bleiglanz (8. Nov 2005)

das geht nicht

wenn du

/foo/bar/com/Abc.class 

findest, dann könnte die Klasse ja

foo.bar.com.Abc

oder

bar.com.Abc

oder

com.Abc

sein, aber um das rauszufinden müsstest du sie erstmal laden...

dazu müsstest du schon den Bytecode analysieren


----------



## Roar (8. Nov 2005)

Bleiglanz hat gesagt.:
			
		

> dazu müsstest du schon den Bytecode analysieren



und das kansnt du schön mit: jclasslib machen  dann brauchste die klasse auch gar nicht zu laden um methoden, felder etc. auslesen zu können.


----------



## hpa42 (9. Nov 2005)

Danke, Bleiglanz
das mit dem Package-Namespace hab mir ich auch überlegt.
Hab aber gehofft, dass sich der Classloader irgendwie so 
hinbiegen lässt, dass er mir die Klasse doch liefert. 
Aber eigentlich  kann das gar nicht gehen, weil er ja ohne 
Namespace keine Instanz anlegen kann und daher  das
Loading fehlschlagen muss. Ist das so?

Kann ich also solche Klassen nur über die Analyse des
Bytecodes lesen? Kann ich den Classloader nur mit korrektem
Packagenamen gebrauchen? wie macht das jclasslib?


----------



## Bleiglanz (9. Nov 2005)

Beispiel mit asm http://asm.objectweb.org/index.html

besorg dir asm-2.1.jar 

http://forge.objectweb.org/project/download.php?group_id=23&file_id=4532

dann sollte damit folgendes funktionieren

("den FQN aus einem ByteArray herausholen")


```
// braucht
import org.objectweb.asm.*;

//aufruf z.B. 
//getClassName(new FileInputStream(new File("binaerdatei"))));

    private static String getClassName(InputStream in) throws IOException, FileNotFoundException {

        final String[] name = new String[1];
        
        ClassReader rd = new ClassReader(in);
        
        rd.accept(new ClassVisitor(){

            public void visit(int arg0, int arg1, String arg2, String arg3, String arg4, String[] arg5) {
               name[0] = arg2.replaceAll("/","\\.");
            }

            public void visitSource(String arg0, String arg1) {}

            public void visitOuterClass(String arg0, String arg1, String arg2) {}

            public AnnotationVisitor visitAnnotation(String arg0, boolean arg1) {return null;}

            public void visitAttribute(Attribute arg0) {}

            public void visitInnerClass(String arg0, String arg1, String arg2, int arg3) {}

            public FieldVisitor visitField(int arg0, String arg1, String arg2, String arg3, Object arg4) {return null;
            }

            public MethodVisitor visitMethod(int arg0, String arg1, String arg2, String arg3, String[] arg4) {return null;}

            public void visitEnd() {}},false);
        
        return name[0];
    }
}
```


----------



## hpa42 (10. Nov 2005)

Danke! Funktioniert so bestens!


----------

