Du verwendest einen veralteten Browser. Es ist möglich, dass diese oder andere Websites nicht korrekt angezeigt werden. Du solltest ein Upgrade durchführen oder ein alternativer Browser verwenden.
angenommen ich habe ein Projekt mit der Klasse Simple.java. Wenn ich dann ein jar-Archiv hinzufüge, welches ebenfalls die Klasse Simple.java enthält (gleiche Package-Struktur), wie kann ich dann zwischen den beiden unterscheiden?
Klingt vielleicht blödsinnig, aber es geht z.B. darum zwei verschiedene Versionen zu vergleichen (deswegen sind auch Package-Struktur und Klassennamen immer gleich).
Garnicht. Wenn die Klassen vom selben ClassLoader geladen werden, "gewinnt" eine Klasse und die andere gleichnamige ist nicht sichtbar. Welche gewinnt, kann ich nicht sagen, habe es noch nicht ausprobiert.
Hmm, dann muss ich mir wohl etwas anderes einfallen lassen, aber danke für deine Antwort.
Es "gewinnt" übrigens die nicht extern hinzugefügte, nebenbei bemerkt
Du musst die Classen mit unterschiedlichen Classloadern laden. Die entsprechenden Jar duerfen dann natuerlich nicht auf dem Default-Classpath liegen und du musst die Classen via Reflection laden und ausfuehren.
Java:
URL url1= new URL("file:///path/to/package1.jar");
URLClassLoader loader1 = URLClassLoader.newInstance(new URL[] { url });
Class clazz = loader.loadClass("name.of.your.Class");
System.out.println(clazz);
Als Alternative kannst du den Code, der auf die speziellen Klassen zugreift, in einen Thread auslagern. In dem Fall kannst du dann auf die Klassen ganz normal zugreifen.
Java:
URLClassLoader cl = new URLClassLoader(urls);
Thread thread = new MyThread();
thread.setContextClassLoader(cl);
thread.start();
Auf die Idee mit verschiedenen Classloadern bin ich auch schon gekommen. Aber ich glaube das reicht noch nicht ganz aus.
Ich hab mein jar file, wie von dir beschrieben, auch mit dem URLClassLoader geladen und konnte dadurch tatsächlich eine Instanz der entsprechenden Klasse erzeugen. Die Methoden müssten allerdings (extra zu Testzwecken) verschiedene Ergebnisse liefern, was sie nicht tun.
Ich vermute, dass der URLClassLoader den Aufruf delegiert und ich somit immer zwei Instanzen der selben Klasse erhalte, da der Name ja schon bekannt ist. Müsste ich also folglich einen eigenen Classloader schreiben, welcher den Aufruf nicht delegiert?
Der URLClassLoader wird erst den DefaultClassLoader (parent) anfragen ob er die Klasse bereits geladen hat. Falls ja wird er diese zurueckgeben. Wenn nicht wird er die Klasse in seinem Pfad suchen.
Die Klasse, die du ueber den Classloader laden willst darf NICHT im default Classpath liegen. Du musst beide Versionen in ein eigenes Jar auslagern und diese via 2 verschiedenen Classloader laden. Also den gleichen Code nur mit dem 'package2.jar'.
Die Klasse Simple.class darf nur in package1.jar oder package2.jar vorhanden sein.
Classloading ist etwas vom kompliziertesten in Java da die Abhaengigkeiten zwischen den Libraries sauber getrennt werden muessen, ansonsten werden die falschen Klassen geladen oder es hagelt ClassloaderExceptions.
Mit folgendem Code kannst du feststellen aus welchem Jar deine Klasse geladen wurde: