Class-Objekt mit URLClassloader

ThomasT

Mitglied
Hallo,

ich möchte folgendes machen.
Im ersten Schritt (um den es geht) möchte ich jar-Files nach Klassen durchsuchen, die ein bestimmtes Interface implementieren. Ich möchte nur wissen, welche Klassen das machen. Egal ob als Class- oder String-Liste. Invoken will ich sie erst viel später.

Ich versuche eine Klasse, die mir durch Entzippen des Jars namentlich bekannt ist mit URLClassLoader zu laden:

Java:
final URLClassLoader cl = new URLClassLoader(jarUrls.toArray(new URL[jarUrls.size()]));
final Class<?> klasse = cl.loadClass(className);

Dann möchte ich sowas machen:

Java:
if (klasse.isAssignableFrom(base)) ...

Der Classloader läd die Klasse.
Leider ist das Classobjekt bis auf den Namen leer. Kein Feld scheint gesetzt zu sein, wie inspizieren zeigt. Daher gehen Abfragen wie isAssignableFrom() immer schief. Auch das Array der Interfaces (klasse.getInterfaces()) ist leer.

Was mache ich falsch, vergessen ich? Und wie wäre es richtig. Danke.

Gruß Thomas
 
N

nillehammer

Gast
Ich kann den Fehler, dass die Klasse nach dem Laden duch einen Classloader nicht richtig initialisiert ist, nicht reproduzieren. Aber das hier:
Java:
if (klasse.isAssignableFrom(base)) ...
gibt immer false, weil der Aufruf genau falsch rum ist. Zum Nachvollziehen folgender Code:
Java:
// Ein Beispiel mit Interface und Implementierung:
// String ist Kind, Serializable ist base
    System.out.println("String assignable from Serializable: "
        + String.class.isAssignableFrom(Serializable.class));

    System.out.println("Serializable assignable from String: "
        + Serializable.class.isAssignableFrom(String.class));

// Und ein Beispiel mit Klasse und Kind
// Integer ist Kind, Number ist base
    System.out.println("Integer assignable from Number: "
        + Integer.class.isAssignableFrom(Number.class));

    System.out.println("Number assignable from Integer: "
        + Number.class.isAssignableFrom(Integer.class));
 
Zuletzt bearbeitet von einem Moderator:

ThomasT

Mitglied
Ich kann den Fehler, dass die Klasse nach dem Laden duch einen Classloader nicht richtig initialisiert ist, nicht reproduzieren

D.h. im Inspektor siehst du nicht alle Felder mit null belegt?

gibt immer false, weil der Aufruf genau falsch rum ist.

Ja. Schon klar. Hatte ich nur die falsche Zeile kopiert. Es geht auch nicht andersrum. Das ist der Punkt. Das verkehrt herum war ein Verzweiflungsversuch ...
 
N

nillehammer

Gast
ThomasT hat gesagt.:
D.h. im Inspektor siehst du nicht alle Felder mit null belegt?
Doch, aber das liegt daran, dass die Felder nur caches sind, die on the fly initialisiert werden und nicht direkt nach dem Erzeugen der Class-Instanz. Das ist also ganz normal. Mit "nicht reproduzieren" meinte ich, dass ich die Methoden des Class-Objekts aufrufen konnte und sie die erwarteten Werte zurück geliefert haben. Sorry für die ungenaue Ausdrucksweise.

Auch hier wieder Code zum Nachvollziehen:
Java:
    // hier Breakpoint setzen und dann mit Step-Over
    final Class<?> clazz = getClass().getClassLoader().loadClass(
        "java.lang.String");
    
    // Pseudo-Befehl zum Anhalten beim Debugging
    // An dieser Stelle sind alle Felder von clazz noch null
    System.out.println();
    
    // Hier wird was mit clazz gemacht, dass zur initialisierung
    // des Feldes "declaredPublicMethods führt"
    clazz.getMethods();
    
    // Hier wieder anhalten. Jetzt siehst Du im Inspektor, dass
    // das Feld "declaredPublicMethods" mit einer SoftReference belegt ist
    System.out.println();
 
Zuletzt bearbeitet von einem Moderator:

Ebenius

Top Contributor
Hm, ich kann Dein Problem nicht nachvollziehen. Ich habe eine Klasse:

Java:
package com.ebenius;

import java.io.File;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.Arrays;
import java.util.Collection;

/** Test loading a class with two different class loaders. */
public class ClassLoaderTest {

  /** Test main method. */
  public static void main(String[] args) throws Exception {
    final File cwd = new File(System.getProperty("user.dir"));
    final File classDir = new File(cwd, "alternative-bin");
    final URL[] urls = new URL[] { classDir.toURI().toURL() };
    final URLClassLoader cl1 = new URLClassLoader(urls);
    final URLClassLoader cl2 = new URLClassLoader(urls);

    final Class<?> class1 = cl1.loadClass("com.ebenius.LoadThisClass");
    final Class<?> class2 = cl2.loadClass("com.ebenius.LoadThisClass");
    System.out.println("a.1) Class Name of Class 1: " + class1);
    System.out.println("a.2) Class Name of Class 2: " + class2);

    System.out.println("b) Class 1 not equal to Class 2: "
          + !class1.equals(class2));

    System.out.println("c.1) Class 1 assignable to"
          + " com.ebenius.ClassLoaderTest: "
          + ClassLoaderTest.class.isAssignableFrom(class1));
    System.out.println("c.2) Class 2 assignable to"
          + " com.ebenius.ClassLoaderTest: "
          + ClassLoaderTest.class.isAssignableFrom(class2));

    System.out.println("d.1) Class 1 extends com.ebenius.ClassLoaderTest: "
          + (ClassLoaderTest.class == class1.getSuperclass()));
    System.out.println("d.2) Class 2 extends com.ebenius.ClassLoaderTest: "
          + (ClassLoaderTest.class == class2.getSuperclass()));

    System.out.println("e.1) Class 1 assignable to java.io.Serializable: "
          + java.io.Serializable.class.isAssignableFrom(class1));
    System.out.println("e.2) Class 2 assignable to java.io.Serializable: "
          + java.io.Serializable.class.isAssignableFrom(class2));

    System.out.println("f.1) Class 1 assignable to java.lang.Cloneable: "
          + java.lang.Cloneable.class.isAssignableFrom(class1));
    System.out.println("f.2) Class 2 assignable to java.lang.Cloneable: "
          + java.lang.Cloneable.class.isAssignableFrom(class2));

    final Collection<Class<?>> interfaces =
          Arrays.asList(new Class<?>[] { java.io.Serializable.class,
            java.lang.Cloneable.class });
    System.out.println("g.1) Class 1 interfaces are java.io.Serializable "
          + "and java.lang.Cloneable: "
          + interfaces.containsAll(Arrays.asList(class1.getInterfaces())));
    System.out.println("g.2) Class 2 interfaces are java.io.Serializable "
          + "and java.lang.Cloneable: "
          + interfaces.containsAll(Arrays.asList(class2.getInterfaces())));

    System.out.println("h.1) Class 1 has the public method foo(): "
          + (class1.getMethod("foo", new Class<?>[0]) != null));
    System.out.println("h.2) Class 2 has the public method foo(): "
          + (class2.getMethod("foo", new Class<?>[0]) != null));
  }
}
Die Klasse liegt kompiliert in ./bin/com/ebenius/ClassLoaderTest.class .

Ich habe eine zweite Klasse:
Java:
package com.ebenius;

/** Class to load from {@link ClassLoaderTest}. */
public class LoadThisClass extends ClassLoaderTest
    implements java.lang.Cloneable, java.io.Serializable {

  private static final long serialVersionUID = 1L;

  public void foo() {}
}
Diese Klasse liegt kompiliert in ./alternative-bin/com/ebenius/LoadThisClass.class .

Ich starte meine Anwendung:
Code:
java -cp ./bin com.ebenius.ClassLoaderTest
a.1) Class Name of Class 1: class com.ebenius.LoadThisClass
a.2) Class Name of Class 2: class com.ebenius.LoadThisClass
b) Class 1 not equal to Class 2: true
c.1) Class 1 assignable to com.ebenius.ClassLoaderTest: true
c.2) Class 2 assignable to com.ebenius.ClassLoaderTest: true
d.1) Class 1 extends com.ebenius.ClassLoaderTest: true
d.2) Class 2 extends com.ebenius.ClassLoaderTest: true
e.1) Class 1 assignable to java.io.Serializable: true
e.2) Class 2 assignable to java.io.Serializable: true
f.1) Class 1 assignable to java.lang.Cloneable: true
f.2) Class 2 assignable to java.lang.Cloneable: true
g.1) Class 1 interfaces are java.io.Serializable and java.lang.Cloneable: true
g.2) Class 2 interfaces are java.io.Serializable and java.lang.Cloneable: true
h.1) Class 1 has the public method foo(): true
h.2) Class 2 has the public method foo(): true
Das Ergebnis ist genau wie erwartet. Die Klasse ist zweimal von voneinander unabhängigen ClassLoader-Instanzen geladen worden, deswegen sind class1 und class2 nicht gleich. Die Verknüpfungen zu allen über den Parent-ClassLoader geladenen Abhängigkeiten sind genau wie sie sein müssen.

Ebenius
 
N

nillehammer

Gast
So und hier nochmal der Code, mit dem ich ursprünglich getestet habe. Wie gesagt, konnte Deine Fehler nicht reproduzieren. Vielleicht fängst Du auch so "klein" an wie ich (nur eine URL, Array direkt bauen und nicht über Umweg toArray() etc.):
Java:
    final URL jarUrl = new URL(
        "file:///C:/nille/.m2/repository/jdom/jdom/1.0/jdom-1.0.jar");

    final URL[] jarUrls = { jarUrl };

    // URLClassLoader hat eine Factory Methode (newInstance). Die
    // sollte man bevorzugt benutzen, aber mit Konstruktor geht es auch.
    final ClassLoader cl = new URLClassLoader(jarUrls);

    final Class<?> clazz = cl.loadClass("org.jdom.Text");

    // Ein ganzer Wust von Methodensignaturen u.a. auch die Infrastrukturmethoden
    // toString, hashCode etc.
    System.out.println(Arrays.toString(clazz.getMethods()));

    // Superklasse: org.jdom.Content 
    System.out.println(clazz.getSuperclass());
    
    // Ist hier leer, weil Text keine Interfaces implementiert,
    // vielleicht eine Fehlerursache?
    System.out.println(Arrays.toString(clazz.getInterfaces()));
 

ThomasT

Mitglied
Danke soweit. Ihr habt mir, glaub ich, weitergeholfen.
Ich muss das wirklich mal von "klein auf" probieren. Irgendwo stimmt hier was nicht ...

Zumal es mit inneren Klassen wie FileFilter geht!

Ich probier mal weiter.
 

Ebenius

Top Contributor
Über welchen ClassLoader wird denn die [c]base[/c] geladen? Wenn Du diese Klasse / dieses Interface schon über einen anderen ClassLoader lädst, dann muss Dein URL-ClassLoader diesen ClassLoader als Parent bekommen.

Ebenius
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
N Methodenverwendung in Quelltext oder Class-Objekt suchen? Allgemeine Java-Themen 14
D NoClassDefFoundError: Could not initialize class Allgemeine Java-Themen 0
J Class to link Java Allgemeine Java-Themen 4
C Was passt hier nicht bei der Calendar-Class Allgemeine Java-Themen 2
E Class.getResourceAsStream() gibt null zurück Allgemeine Java-Themen 2
Erwin82a Object cannot be converted to Custom Class in Lampda Expression Allgemeine Java-Themen 2
T Java Robot Class - Bot Allgemeine Java-Themen 3
S Class File Editor -> Source not found Allgemeine Java-Themen 4
G javafx "class path" exception Allgemeine Java-Themen 5
S Java class direved from inner class Allgemeine Java-Themen 6
S Inner Class Allgemeine Java-Themen 11
K Wildcard und class type Allgemeine Java-Themen 9
M Java model class ? Allgemeine Java-Themen 9
Thallius Ist meine static Helper Class Thread save? Allgemeine Java-Themen 9
S class path resource [config.properties}] cannot be opened because it does not exist Allgemeine Java-Themen 4
J Reflection Aufruf: .class durch .dll ersetzen Allgemeine Java-Themen 4
T Compiler-Fehler NoClassDefFoundError beim Laden einer Class Allgemeine Java-Themen 11
J Class Decompile als String (Procyon) Allgemeine Java-Themen 2
H Class 'java.io.BuferedReader' is not present in JRE Emulation Libary | GWT Fehler?! Allgemeine Java-Themen 0
I Datentypen String in class sicher verwahren Allgemeine Java-Themen 17
R Dynimc Class Loading Allgemeine Java-Themen 5
J Inner class + Leer-Konstruktor Allgemeine Java-Themen 1
Neumi5694 Methoden Generic: Rückgabetyp als Class-Parameter übergeben Allgemeine Java-Themen 3
D Collections.sort funktioniert nicht in exportierten .class Dateien Allgemeine Java-Themen 10
V Eclipse .class Dateien Allgemeine Java-Themen 9
KeexZDeveoper Von .class zu .java Allgemeine Java-Themen 7
N Wo ist Object.class ? Allgemeine Java-Themen 0
K Nicht alle class-Dateien im JRE? Allgemeine Java-Themen 2
M *.class Files ausführen Allgemeine Java-Themen 2
L Klassen Nested Class In Nested Class Allgemeine Java-Themen 3
perlenfischer1984 Dialect class not found exception Allgemeine Java-Themen 15
Tort-E Manifest Main-Class Allgemeine Java-Themen 8
I JSoup Class auslesen Allgemeine Java-Themen 1
K Generic class und Reflection Allgemeine Java-Themen 2
R .class Datei in .jar austauschen Allgemeine Java-Themen 2
R Java .class-File-Konstrunkt mit Programm visualisieren Allgemeine Java-Themen 18
A main-class Not found Allgemeine Java-Themen 3
T Java Class Intrumentation mit Annotations in Laufzeit Allgemeine Java-Themen 1
N Per Reflection auf (method) local inner class zugreifen? Allgemeine Java-Themen 3
P JDK installieren Error: Could not find or load main class HelloWorld.java Allgemeine Java-Themen 3
B public class JarFilter extends FileFilter « Falsch? Allgemeine Java-Themen 4
D Object nach Vererbung mit Class Object überprüfen Allgemeine Java-Themen 4
T Hash von *.class-Datein überprüfen Allgemeine Java-Themen 1
F java.lang.ClassNotFoundException: .class Allgemeine Java-Themen 5
T InvalidClassException - Read null attempting to read class descriptor for object Allgemeine Java-Themen 8
Phash Can't find Main Class Allgemeine Java-Themen 4
B Erste Schritte Plugin erkennen und Class Dateien anzeigen lassen Allgemeine Java-Themen 3
B json zu java class Allgemeine Java-Themen 2
antonbracke Aus Jar eine Class laden und damit arbeiten! Allgemeine Java-Themen 5
D Class<CAP#1> statt Class<...> Allgemeine Java-Themen 5
A Class Datei aus Verzeichnis über URLClassLoader laden Allgemeine Java-Themen 2
L Class Files , Methode .delete() Allgemeine Java-Themen 13
E NetBeans warning: [options] bootstrap class path not set in conjunction with -source 1.6 Allgemeine Java-Themen 4
X Could not find the main class programm will exit (textdokument) Allgemeine Java-Themen 3
S Could not find the main class Allgemeine Java-Themen 7
B Mal wieder "Could not find the main class" Allgemeine Java-Themen 3
B Variable class in java.lang.Object Allgemeine Java-Themen 11
C Could not find the main class. Allgemeine Java-Themen 15
S Klassen .jar - eine .class datei ändern? Allgemeine Java-Themen 23
A Could not find main class: start Allgemeine Java-Themen 5
S main() class finden Allgemeine Java-Themen 7
hdi Could not find main class? Allgemeine Java-Themen 8
R Warum Class.forName(); Allgemeine Java-Themen 7
C class.class angefordert ? Allgemeine Java-Themen 2
S Methoden Class.forName() >> Methoden - Reihenfolge Allgemeine Java-Themen 5
B Test$1.class mit dem javac compiler Allgemeine Java-Themen 7
G jar Datei findet Main Class nicht... Allgemeine Java-Themen 2
P Java Editor Could not find the main class GUI. Programm will exit. Allgemeine Java-Themen 3
D class Datei einlesen Allgemeine Java-Themen 4
T Interface > Abstract > Class Allgemeine Java-Themen 11
TheDarkRose Subversion .class Dateien auch commiten? Allgemeine Java-Themen 3
D API - Beispiel + static member in inner (non static) class Allgemeine Java-Themen 2
E String name in class convertieren Allgemeine Java-Themen 4
F Änderung in .jar bzw. .class vornehmen ? Allgemeine Java-Themen 18
H2SO3- bestimmte class immer mit 1.4 compilieren Allgemeine Java-Themen 5
B class dateien "einlesen" und objekte erzeugen Allgemeine Java-Themen 6
G Unterschied MyClass.class vs this Allgemeine Java-Themen 2
S mit Class eine Klasse nur einmal instantiieren Allgemeine Java-Themen 4
Sonecc Zugriff auf Class File einer anderen Jar während der Laufzeit Allgemeine Java-Themen 2
M Klasse aus xyz.class Datei laden / package entfernen? Allgemeine Java-Themen 4
BattleMaster246 Could not find the Main class Allgemeine Java-Themen 30
N class Task extends TimerTask ohne Blockieren Allgemeine Java-Themen 15
H .class in .java umwandeln Allgemeine Java-Themen 3
T class.newinstance + try/catch-konstruktor Allgemeine Java-Themen 6
X Cannot refer to a non-final variable settings inside an inner class defined in a different method Allgemeine Java-Themen 4
J Class.forName und CLASSPATH -Problem Allgemeine Java-Themen 5
T Class-files zur Laufzeit zu Reflection-Zwecken laden Allgemeine Java-Themen 18
G Thread in Methode oder in inner class Allgemeine Java-Themen 3
woezelmann referenz der outer class aus static nested class heraus Allgemeine Java-Themen 7
reibi Main-Class in Jarfile Allgemeine Java-Themen 3
E Timer class macht einfach garnichts :/ Allgemeine Java-Themen 6
D Class.forName Allgemeine Java-Themen 2
S Class RGB Farbe Allgemeine Java-Themen 2
S JavaDoc aus .class Datei extrahieren Allgemeine Java-Themen 5
mongole Class.class.getResource(...) Allgemeine Java-Themen 10
N Probleme mit .jar 'Could not find main class' Allgemeine Java-Themen 3
T Class Not Found Exception beim import von Paket Allgemeine Java-Themen 2
G Abstract class Stillfrage Allgemeine Java-Themen 4
P Class Casting: Graphics/Graphics2D Allgemeine Java-Themen 7
H2SO3- abstract class mit Beispielen in abstracten Methoden Allgemeine Java-Themen 5

Ähnliche Java Themen

Neue Themen


Oben