Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » Java » Klasse zur Laufzeit laden

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 <
000
09.12.2007, 11:52 Uhr
~FreiherrEintritt
Gast


hoppla......

Ich versuche eine Klasse aus einer .class-Datei zur Laufzeit zu laden, nur leider sagt er mir, dass die Methode define(byte[], int, int) für die Klasse ClassLoader nicht definiert sei. Meiner Meinung nach ist sie das aber, und zwar als protected. Warum kann ich darauf nicht zugreifen?


C++:
public class MyLoader extends ClassLoader {

    public Class<?> ladeKlasse(String datei) {
        char[] stream = null;
        int len = 0;
        try {
            // Dateilänge ermitteln:
            RandomAccessFile raf = new RandomAccessFile(datei, "r");
            len = (int)raf.length();
            raf.close();
            System.out.println("Dateilänge beträgt " + len);
            // Byteweise einlesen:
            stream = new char[len];
            FileReader fr = new FileReader(datei);
            fr.read(stream);
            fr.close();
            System.out.println("Datei gelesen");
        } catch (FileNotFoundException e) {
            System.err.println("Datei nicht gefunden");
            return null;
        } catch (IOException e) {
            System.err.println("IO-Fehler: " + e.getMessage());
        }
        byte[] cDef = new byte[len];
        try {
            // Char-Array in Byte-Array umwandeln:
            for(int i=0; i<len; i++) cDef[i] = (byte)stream[i];
            // Instanz der Klasse erzeugen:
            return define(cDef, 0, len);     // ***** Hier passierts *****
        } catch(ClassFormatError e) {
            System.err.println("Byte-Array ungültig");
        } catch(IndexOutOfBoundsException e) {
            System.err.println("Ungültiger Offset/Länge");
        } catch(SecurityException e) {
            System.err.println("Ungültige Klasse");
        }
        return null;
    }
    
}

 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
09.12.2007, 18:51 Uhr
Kest
saint


Hi!

Wie sieht denn >ClassLoader< aus?
--
Wenn man einen Hufschlag hört, sollte man >Pferd< denken und nicht >Zebra<.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
10.12.2007, 09:47 Uhr
~FreiherrEintritt
Gast


Das ist die offizielle java.lang.ClassLoader
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
10.12.2007, 11:29 Uhr
virtual
Sexiest Bit alive
(Operator)


Hallo,


Zitat von ~FreiherrEintritt:


C++:
public class MyLoader extends ClassLoader {

    public Class<?> ladeKlasse(String datei) {
        char[] stream = null;
        int len = 0;
        try {
            // Dateilänge ermitteln:
            RandomAccessFile raf = new RandomAccessFile(datei, "r");
            len = (int)raf.length();
            raf.close();
            System.out.println("Dateilänge beträgt " + len);
            // Byteweise einlesen:
            stream = new char[len];
            FileReader fr = new FileReader(datei);
            fr.read(stream);
            fr.close();
            System.out.println("Datei gelesen");
        } catch (FileNotFoundException e) {
            System.err.println("Datei nicht gefunden");
            return null;
        } catch (IOException e) {
            System.err.println("IO-Fehler: " + e.getMessage());
        }





Das ist völlig ungeeignet: char!=byte, da hilft auch kein casten. Du musst zwingend einen Byte basierten Inputstream nutzen, etwa den java.io.FileInputStream

Der Aufruf der defineClass - Methode ist prinzipiell richtig, wenn Du davor nicht die Klassenbytes zermatschst, wie Du es durch die Umwandlung von char -> byte tust.

Die Methode "ladeKlasse" solltest Du auch besser direkt findClass nennen, also die Implementierung der Basisklasse überschreiben.
--
Gruß, virtual
Quote of the Month
Ich eß' nur was ein Gesicht hat (Creme 21)

Dieser Post wurde am 10.12.2007 um 11:30 Uhr von virtual editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
004
10.12.2007, 12:21 Uhr
~Freiherr
Gast


Oh... ich wusste nicht, dass char in Java schon 16 bit breit sind......
Aber unabhängig davon: Mein Problem war nicht, dass der obige Code nicht funktioniert, weil im Array Müll drin steht, sondern dass mir der Compiler sagt, dass die Methode define für die Klasse ClassLoader nicht definiert sei. Laut JavaDoc ist sie das aber.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
005
10.12.2007, 12:42 Uhr
FloSoft
Medialer Over-Flow
(Administrator)


muss man die methoden der basisklasse in java nich mit super().method() aufrufen oder sowas?
--
class God : public ChuckNorris { };
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
006
10.12.2007, 12:50 Uhr
virtual
Sexiest Bit alive
(Operator)


@Freiherr
Die Methode heisst ja auch defineClass und nicht define

@FloSoft
Noe, kommt auf die genaue Situation an. In dieser eben nicht.
--
Gruß, virtual
Quote of the Month
Ich eß' nur was ein Gesicht hat (Creme 21)
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
007
10.12.2007, 14:48 Uhr
~FreiherrEintritt
Gast


Danke, ich bin echt blind......
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
008
15.12.2007, 16:32 Uhr
~FreiherrEintritt
Gast


Ich hab die beiden Fehler verbessert und hab jetzt folgenden Quelltext:


C++:
public class MyLoader extends ClassLoader {
    
    public Class<?> findClass(String filename) {
        long len = 0;
        byte[] stream = null;
        try {
            RandomAccessFile raf = new RandomAccessFile(filename, "r");
            len = raf.length();
            System.out.println("Dateilänge beträgt: " + len);
            stream = new byte[(int)len];
            raf.read(stream);
            raf.close();
            System.out.println("Datei gelesen");
        } catch (FileNotFoundException e) {
            System.err.println("Datei nicht gefunden");
            return null;
        } catch (IOException e) {
            System.err.println("IO-Fehler: " + e.getMessage());
        }
        try {
            return defineClass(null, stream, 0, (int)len);
        } catch(ClassFormatError e) {
            System.err.println("Byte-Array ungültig");
        } catch(IndexOutOfBoundsException e) {
            System.err.println("Ungültiger Offset/Länge");
        } catch(SecurityException e) {
            System.err.println("Ungültige Klasse");
        }
        return null;
    }
    
}



Das ganze wird hier benutzt:

C++:
public class Laden {
    
    public static void main(String[] args) {
        MyLoader cl = new MyLoader();
        Class<?> dummy = cl.findClass("C:\\EinDummy.class");
        if(dummy == null) {
            System.err.println("Laden der Klasse fehlgeschlagen");
            return;
        }
        System.out.println("Anzahl Methoden: " + dummy.getDeclaredMethods().length);
        Method[] methods = dummy.getDeclaredMethods();
        for(int i=0; i<methods.length; i++) {
            System.out.println(methods[i].toString());
            try {
                methods[i].invoke(dummy);
            } catch (InvocationTargetException e) {
                System.err.println("Exception aus SagA-Methode");
            } catch (IllegalAccessException e) {
                System.err.println("Zugriff auf Methode von hier aus verboten");
            } catch (IllegalArgumentException e) {
                System.err.println("Falsches Objekt: " + e.getMessage());
            }
        }
    }
}



Das Laden der Klasse funktioniert, es werden alle Methoden erkannt.
invoke soll als erstes Argument das Objekt bekommen, dem die aufzurufende Methode gehört (und dann optional Paramter an dieselbe). So habe ich es auch in vielen Beispielen im Netz gesehen. Leider wird eine IllegalArgumentException geworfen, was genau dann passiert, wenn das erste Argument falsch ist.
Was soll ich da bitte sonst übergeben?
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 <     [ Java ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: