public class FileClassLoader extends ClassLoader {
public Class findClass(String fileName) throws ClassNotFoundException {
FileInputStream file = null;
try {
file = new FileInputStream(fileName);
byte[] classBytes = new byte[file.available()];
file.read(classBytes);
Class loadedClass = defineClass(null, classBytes, 0,
classBytes.length);
return loadedClass;
} catch (Exception exception) {
exception.printStackTrace();
throw new ClassNotFoundException(fileName);
} finally {
if (file != null) {
try {
file.close();
} catch (Exception exception) {
exception.printStackTrace();
}
}
}
}
}
---
Hmm, dieser FileClassLoader funktioniert nicht so wie "forName("");" -
sollte er aber. Könnte mir jemand sagen, wo der Fehler liegt ?
Gruß,
Sascha
Remo
Exception wird keine ausgelöst nur ich habe das dumpfe Gefühl, das das ganze
nicht so funktioniert wie Class.forName.
hmm ... les dir einfach noch mal den Beitrag
mailto:9a5n7k$252$1...@Merlin.et.bocholt.fh-gelsenkirchen.de durch.
Hast du die Doku zu java.lang.Classloader.findClass gelesen?
Diese Methode wird von der loadClass()-Methode aufgerufen,
wenn die Klasse nicht anderweitig gefunden werden konnte.
Und die Methode wird aufgerufen mit einem Klassennamen - z.B.
"test.Resource", nicht mit einem Dateinamen.
Ich würde folgende Änderungen vornehmen:
> ---
> import java.io.*;
> import java.lang.*;
> import java.util.*;
>
> public class FileClassLoader extends ClassLoader {
private String root;
public FileClassLoader(String directory)
{
this.root = directory;
}
>
> public Class findClass(String className) throws ClassNotFoundException {
> FileInputStream file = null;
> try {
File fileName =
new File(root + File.separator +
className.replace('.', File.separator) + ".java");
> file = new FileInputStream(fileName);
> byte[] classBytes = new byte[file.available()];
> file.read(classBytes);
> Class loadedClass = defineClass(className, classBytes, 0,
C:\classes\test>java test.Tester
Exception in thread "main" java.lang.NoClassDefFoundError: Resource (wrong
name
test/Resource)
at java.lang.ClassLoader.defineClass0(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:486)
at java.lang.ClassLoader.defineClass(ClassLoader.java:426)
at com.FileClassLoader.findClass(FileClassLoader.java:25)
at test.StringLister.listeDieResourcen(StringLister.java:12)
at test.Tester.main(Tester.java:20)
Der FileClassLoader liegt in com (spasshalber ;o)).
Gruß,
Sascha
gruß Torsten Fohrer
So wie ich das sehe, wird entweder die Klasse "Resource" als "test.Resource"
geladen oder umgekehrt. Zeige mir mal Zeile 11-13 von Stringlister.java und
Zeile 1 von Resource.java.
Paul
package test;
--- --- ---
--- StringLister --- 11 - 13 ---
Class cfgClass = getClass();
Class resClass = // Class.forName("test.Resource");
new
FileClassLoader("C:\\classes\\test").findClass("Resource");
--- --- ---
Anmerkung: Die Klassen liegen alle innerhalb "c:\classes\test".
Gruß,
Sascha
Wenn man einen ClassLoader verwendet, sollte man eigentlich die
loadClass-Methode verwenden. Aber selbst bei deiner Variante:
new FileClassLoader("C:\\classes").findClass("test.Resource");
Bei einem ClassLoader sollte man immer den _kompletten_
Klassen-Namen (also mit Package) angeben.
So versuchtest du die Klasse "Resource" im namenslosen (null-)
Package zu laden. Dann gibt es natürlich den Fehler, dass die
Klasse intern anders heißt (nämlich 'test.Resource', wobei das
für die VM in 'test/Resource' umgesetzt wird).
Paul