Zur Laufzeit eine Klasse laden, die auf jar-File zugreift

Status
Nicht offen für weitere Antworten.
L

Litti

Gast
Hallo zusammen,

ich kämpfe seit gestern mit einem Problem, zu dem ich einfach keine Lösung finde. Ich muss zur Laufzeit meines Programmes Klassen nachladen - soweit ja noch kein Problem. Das entsteht erst, wenn diese Klasse dann auch noch auf Jar-Bibliotheken zugreifen will (Name dieser Jar ist bekannt).
Ich habe das Szenario einfach mal auf das Wichtigste gekürzt und getestet, hier meine Test-Klasse (alle Files liegen im gleichen directory):

Code:
try
{
   URL urls [] = new URL[2];
   urls[0] = new URL("file:./JarTest");
   urls[1] = new URL("file:./JarFile.jar");
   URLClassLoader cl = new URLClassLoader (urls);
            
   // PutString gibt einfach in der toString() ein "hiho" zurück
   Class oClass = cl.loadClass("PutString");
   Object o = (Object)oClass.newInstance();

   System.out.println(o);	

   System.out.println ("Success!");

   // ITest ist ein Interface mit der Methode setFields()
   // JarTest implementiert ITest, erstellt in setFields() eine Klasse PutString und
   // gibt in der toString die toString von PutString zurück (also "hiho")
   Class iTestClass = cl.loadClass("JarTest");
   ITest test = (ITest)iTestClass.newInstance();
	   
   System.out.println ("Success!");	
	   
   test.setFields();
   System.out.println(test);
}catch (Exception ex)
{
   System.out.println ("Failed.");
   ex.printStackTrace ();
}

Ausgabe beim Ablaufen der Klasse:

Code:
hiho
Success!
Success!
Exception in thread "main" java.lang.NoClassDefFoundError: PutString
        at JarTest.setFields(JarTest.java:6)
        at Test.main(Test.java:28)

Ich mache da wohl einen grundsätzlichen Fehler beim Umgang mit ClassLoadern. Wäre toll wenn mir wer weiterhelfen könnte, oder auch nur einen Anstoß, eine Idee...

LG Litti
 

thE_29

Top Contributor
Deine Klasse heißt PutString?

Class oClass = cl.loadClass("PutString")

hier muss der Klassennamen + package angegeben sein!
 
L

Litti

Gast
Hm ja hab das an der Stelle vlt etwas schlecht erklärt:

PutString ist Bestandteil der JarFile.jar. Diese jar übergebe ich zu Beginn dem ClassLoader. Dann hole ich mir PutString einmal direkt heraus, um zu sehen ob es zunächst einmal soweit funktioniert. Ist auch der Fall, da "Success" und "hiho" ausgegeben werden. Dann hole ich mir die Klasse JarTest, die ebenfalls PutString nutzt. Jetzt greife ich also indirekt auf PutString zu, eben über die Klasse JarTest: JarTest implementiert ein Interface, welches die Methode setFields() definiert. In dieser Methode wird dann ein Objekt von PutString erstellt --> wie man an der Ausgabe sieht, kommt der ClassLoader mit diesem indirekten Aufruf nicht mehr zu Recht, da ihm PutString nun plötzlich unbekannt ist...

Ich hoffe es ist ungefähr klar was ich vorhab...ich will Klassen zur Laufzeit laden, die eben auch sonst nur mit einem "javac -cp jarfile.jar Klasse.java" kompiliert werden könnten.
 
L

Litti

Gast
Hat keiner irgendwelche Ideen? Ich vermute mal es hat was mit diesem ganzen ClassLoader-Konzept von Java zu tun, bei dem ich scheinbar noch nicht ganz durchsteig...
 

Wildcard

Top Contributor
Eine Klasse kann prinzipiell erstmal nur einmal geladen werden. Die einzige Möglichkeit sie wieder zu entladen, besteht darin, den ClassLoader wegzuwerfen. Du wirfst deinen Classloader wohl weg.
 
G

Guest

Gast
Danke für die Antwort, leider versteh ich sie nicht ganz...
Glaubst du es liegt daran, dass ich die Klasse PutString bereits einmal geladen habe, bevor JarTest es selbst tun müsste? Habe ich ausprobiert, in dem ich das erste Laden von PutString auskommentiert habe: kein Erfolg, selbe Fehlermeldung.
Ich will ja auch keine Klasse entladen, sondern einfach folgendes: Eine Klasse laden, die nur mit einer (ebenfalls zur Compilezeit unbekannten) jar-Bibliothek funktioniert. Also muss ich auch dieses jar-File nachladen (Name und Ort bekannt). Aber wie muss ich das nun mit den ClassLoadern regeln, damit auch erkannt wird, dass die Inhalte der jar ja längst geladen sind?
 

cburghardt

Mitglied
Noch komplizierter gehts's ja nicht, zum Kompilieren von JarTest brauchst du die PutString ja auch, somit verstehe ich den Sinn und Zweck von deinem dynamischen Laden nicht so richtig, wenn du eine Abhängigkeit zur Compile-Zeit hast.

Anyway, ich bin mir nicht ganz sicher, aber versuch mal:
Code:
Class iTestClass = cl.loadClass("JarTest", true);
 
L

Litti

Gast
Funktioniert leider auch...nach dem Umbau des Programms (Zugriff auf Methode ist ja protected) selbe Fehlermeldung.

Puh, bitte sagt mir dass es dazu irgendeine Lösung gibt. Das Jar-File ist ja vorhanden, irgendwas muss da doch zu machen sein...
 

thE_29

Top Contributor
Also eigentlich müsste das doch so gehen!

Hier ist mein Code zum Laden eines Jar Files

Code:
    File fJar = new File(strJar);
    URL url = null;
    try
    {
      //holt sich das jar file in url form
      url = fJar.toURL();
      URLClassLoader urlcl = new URLClassLoader(new URL[]   {url});
      Class clazz = Class.forName(strPackage, true, urlcl);
      Constructor cons = null;
      cons = clazz.getConstructor(formparas); //holt den Konstruktor über Objekte
      currentProgram = cons.newInstance(actargs); //startet den Konstruktor und somit das Programm und merkt sich das Objekt
    catch (Exception ex)
{
ex.printStackTrace();
}

Die Frage ist halt, ob er die anderen Dateien die man dem URLClassLoader übergibt auch mit berücksichtigt oder nicht!

Könntest du eventuell deine Testsituation irgendwo bereitstellen?
 

cburghardt

Mitglied
Das Problem ist ja nicht die Instanziierung sondern die Verwendung von PutString in der Klasse JarTest

Könntest du mal die PutString hier posten, vielleicht gibts eine Abhängigkeit
 
G

Guest

Gast
Super dass ihr versucht mir zu helfen!

Hier die PutString, aber ich weiß nicht ob euch das wirklich hilft...

Code:
public class PutString {
	
	public String toString(){
		return "hiho";
	}
}

Also wirklich nur die toString() überschrieben. Diese Datei ist einziger Bestandteil der JarFile.jar. TestClass nutzt diese Bibliothek indem sie in der Methode setFields() (vorgegben durchs Interface ITest) ein PutString-Objekt erzeugt.
 

cburghardt

Mitglied
Mysteriös, dann kann es nichts mit dem Classloader zu tun haben, weil die Klasse ja instanziiert werden kann.
Gab es nach der Änderung beim loadClass(.., true) die gleiche Fehlermeldung? Nebenbei gesagt: der bessere Weg wäre übrigens
Class.forName(class, true, classloader)
Dann wird das Objekt nämlich auch initialisiert, was Classloader.loadClass NICHT macht.
NoClassDefFoundError heisst ja, dass zwar eine Klasse mit dem richtigen Namen gefunden wurde, aber die Interfaces zur Laufzeit nicht mehr die gleichen sind wie zur Compilezeit. Wenn also in deiner PutString Klasse nichts importiert wird, kann ich mir nur noch vorstellen dass noch eine andere Version dieser Klasse in deinem Classpath rumhängt.


...Carsten
 

Wildcard

Top Contributor
Um mich zu wiederholen:
Ich behaupte du behälst die Referenz auf deinen URL Classloader nicht.
Sobald der GC ihn eingesammelt hat, ist auch die geladene Class futsch.
 
L

Litti

Gast
Hm, wann genau greift da der gc? Und was müsst ich deiner Meinung nach ändern?

Das mit dem NoClassDefFoundError ist ein guter Hinweis...hatte ich mir gar nicht so klar gemacht, dass das ja noch ein Unterschied zu dem Fall darstellt, dass gar keine Klasse gefunden wird. Aber durch den Classpath dürfte eigentlich nix schief gehen, den hab ger nicht gesetzt und bezieht sich dementsprechend nur aufs akutelle dir.

Ich hab jetzt mal den Code online gestellt, hab das Gefühl damit würd ichs auch euch etwas erleichtern:
test.tar.gz
Auch der Quellcode der PutString ist vorhanden, falls ihr noch einmal ein neues Jar erzeugen wollt.
 
L

Litti

Gast
Ich schieb das mal wieder hoch, ist leider für mich noch immer aktuell.

Und allmählich gibts auch nichts mehr, was ich ohne eine Lösung weitermachen könnte,,,*HELP*
 

thE_29

Top Contributor
Vielleicht solltest du eine Referenz auf den ClassLoader behalten und immer wieder bei new URLClassLoader den alten mitübergeben?!
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
X Collections Gibt es eine Klasse welche die Vorteile von List und HashMap vereint, aber konstante Laufzeit (O(1)) hat in Java? Allgemeine Java-Themen 4
S Build-Zeitpunt (Datum und Uhrzeit) irgendwie während der Laufzeit zugänglich machen..? Allgemeine Java-Themen 4
M Laufzeit des Prim Algorithmus Allgemeine Java-Themen 3
M Laufzeit LinkedList Allgemeine Java-Themen 9
M verbesserte Laufzeit bei LinkedList Allgemeine Java-Themen 7
K Verbesserung der Laufzeit beim Sortieren von Einwohnern nach ihrem Geburtsjahr Allgemeine Java-Themen 0
H was ist den dieses zur Kompilierzeit und zur Laufzeit in Java? Allgemeine Java-Themen 3
L Classpath Zur Laufzeit bestimmte Klassen in Classloader hinzufügen? Allgemeine Java-Themen 4
L Compiler-Fehler Google Guice Module zur Laufzeit zusammenstellen und binden Allgemeine Java-Themen 4
J Jasper Reports - Subreport zur Laufzeit ändern Allgemeine Java-Themen 6
O jar und EXE Dateien, Pfade zur Laufzeit Allgemeine Java-Themen 1
T Externe Java Klasen zur Laufzeit einbinden Allgemeine Java-Themen 10
D Boolean von ein anderem Java Programm während der Laufzeit ändern Allgemeine Java-Themen 23
N Generic Type einer Generischen Klasse während der Laufzeit bekommen Allgemeine Java-Themen 2
J .java-Dateitext Compile zur Laufzeit ohne File Allgemeine Java-Themen 15
kodela Daten während Laufzeit zugriffsbereit Allgemeine Java-Themen 15
Neumi5694 Interpreter-Fehler final Eigenschaft während Laufzeit geändert Allgemeine Java-Themen 2
A Java Klasse auf Tomcat während der Laufzeit austauschen Allgemeine Java-Themen 1
M Sinn von Kompilierung zur Laufzeit Allgemeine Java-Themen 3
T Java Class Intrumentation mit Annotations in Laufzeit Allgemeine Java-Themen 1
S Byte Array welches in Laufzeit aufgelöst wird // Objekt Array Allgemeine Java-Themen 3
T Dateien zur Laufzeit in Java-Programm packen? Allgemeine Java-Themen 3
S Laufzeit Primzahlgenerator Allgemeine Java-Themen 18
S Zur Laufzeit Klasse mit einer anzahl von X Objekten erstellen Allgemeine Java-Themen 5
F Classpath Programmteile zur Laufzeit nachladen Allgemeine Java-Themen 6
D Variablen zur Laufzeit global speichern (Registry Pattern?) Allgemeine Java-Themen 6
H ResourceBundle während Laufzeit bearbeiten Allgemeine Java-Themen 3
J Input/Output Jar-Datei zur Laufzeit erweitern Allgemeine Java-Themen 13
P Generic zur Laufzeit Allgemeine Java-Themen 4
A ar während der Laufzeit überschreiben Allgemeine Java-Themen 20
X MergeSort Laufzeit Problem Allgemeine Java-Themen 4
J Resourcen waehrend der Laufzeit aendern? Allgemeine Java-Themen 9
P Wie bei log4j den Dateipfad der Logdatei zur Laufzeit ändern? Allgemeine Java-Themen 3
X Update einer Jar während der Laufzeit Allgemeine Java-Themen 8
T Klassen Fabrik (Factory) zur Laufzeit erweitern Allgemeine Java-Themen 5
S UML zur Laufzeit ändern Allgemeine Java-Themen 10
E Wert von enum zur Laufzeit festlegen. Allgemeine Java-Themen 5
L Methode in Thread mit langer Laufzeit unterbrechen (ANT executeTarget) Allgemeine Java-Themen 4
O Problem bei Darstellung der Laufzeit eines Programms Allgemeine Java-Themen 3
hdi Ressourcen dynamisch zur Laufzeit laden Allgemeine Java-Themen 15
A Wie zur Laufzeit auf Objekte zugreifen Allgemeine Java-Themen 7
N variable Anzahl von Objektinstanzen zur Laufzeit erstellen Allgemeine Java-Themen 4
P Java Konsole zur Laufzeit einblenden Allgemeine Java-Themen 4
P Klassenwahl zur Laufzeit Allgemeine Java-Themen 5
R Objekt zur Laufzeit zerstören? Allgemeine Java-Themen 12
E formartierte Ausgabe zur Laufzeit Allgemeine Java-Themen 2
Sonecc Zugriff auf Class File einer anderen Jar während der Laufzeit Allgemeine Java-Themen 2
F Wie zur Laufzeit ganz neue Objekte erzeugen? Allgemeine Java-Themen 5
T Class-files zur Laufzeit zu Reflection-Zwecken laden Allgemeine Java-Themen 18
DamienX Debug Modus zur Laufzeit erkennen Allgemeine Java-Themen 3
Stillmatic Debuggen/ Laufzeit von Methoden Allgemeine Java-Themen 2
Dragonfire Generic Typ zur Laufzeit Allgemeine Java-Themen 9
M Klasse zur Laufzeit ersetzen Allgemeine Java-Themen 10
S Wie gross ist die Laufzeit für diese Schleife?? Allgemeine Java-Themen 8
G File zur Laufzeit erzeugen Allgemeine Java-Themen 4
G Jar File zur Laufzeit ändern. Allgemeine Java-Themen 4
T Java - Compilieren während Laufzeit Allgemeine Java-Themen 3
Y JARs austauschen zur Laufzeit Allgemeine Java-Themen 11
G Datenbank zur laufzeit wechseln Allgemeine Java-Themen 11
C Innere Klassen zur Laufzeit Instanzieren Allgemeine Java-Themen 4
T Zur Laufzeit erben? Allgemeine Java-Themen 22
L HashMap / Objekte auf Festplatte zur Laufzeit auf HD swappen Allgemeine Java-Themen 7
V Java-Programm weiss zur Laufzeit wie es gestartet wurde? Allgemeine Java-Themen 6
N Endlosschleifen automatisiert erkennen (Code oder Laufzeit)? Allgemeine Java-Themen 6
G Eindeutiges Identifizieren einer JTable/Component z.laufzeit Allgemeine Java-Themen 2
G Datei durchsuchen, lange Laufzeit! Allgemeine Java-Themen 2
A log4j 1.3 und ändern der log Konfiguration zur Laufzeit Allgemeine Java-Themen 4
Apo Zur Laufzeit Klassen mit Packages laden? Allgemeine Java-Themen 2
G genauen Typ einer generischen Klasse zur Laufzeit ermitteln Allgemeine Java-Themen 2
F Typ eines Objekts zur Laufzeit bestimmen? Allgemeine Java-Themen 8
T xverify-parameter : Workaround zur Laufzeit? Allgemeine Java-Themen 8
M Bibliotheksname zur Laufzeit ermitteln (Classloader) Allgemeine Java-Themen 7
G Klasse wird zur Laufzeit nicht gefunden? Allgemeine Java-Themen 3
@ zur Laufzeit Interface aus jar implementieren? Allgemeine Java-Themen 5
MQue Laufzeit Allgemeine Java-Themen 4
D Lautstärke einzelner AudioClips zur Laufzeit verändern Allgemeine Java-Themen 4
C Mathefunktion zur Laufzeit einlesen und dann verarbeiten Allgemeine Java-Themen 13
G Klassen zur Laufzeit einbinden Allgemeine Java-Themen 3
J Bibliotheken erst zur Laufzeit laden Allgemeine Java-Themen 5
R Drag und Drop - Fehler während Laufzeit Allgemeine Java-Themen 14
byte Generic Type einer List zur Laufzeit rausfinden? Allgemeine Java-Themen 4
A Class File zur Laufzeit laden ohne den Binary Name zu kennen Allgemeine Java-Themen 11
M Überprüfen einer zur Laufzeit geladenen Klasse Allgemeine Java-Themen 3
H Klassen aus einem Ordner zur Laufzeit laden. Allgemeine Java-Themen 6
S Laufzeit und Compilefehler Allgemeine Java-Themen 6
S JPanel zur Laufzeit verbergen bzw. wieder anzeigen lassen Allgemeine Java-Themen 4
F Objektname zur Laufzeit festlegen? Allgemeine Java-Themen 12
I Sprache zur Laufzeit des Programms ändern Allgemeine Java-Themen 3
G Laufzeit eines aus Java gestarteten Programms beobachten Allgemeine Java-Themen 3
S Log4J: Logdatei zur Laufzeit ermitteln. Allgemeine Java-Themen 2
I Zur Laufzeit ermitteln, ob Klasse in JAR-Datei Allgemeine Java-Themen 2
R iText.jar wird zur Laufzeit nicht gefunden Allgemeine Java-Themen 4
J ResourceBundle / properties-datei während der Laufzeit verän Allgemeine Java-Themen 6
H Methode einer zur Laufzeit generierten Instanz aufrufen Allgemeine Java-Themen 2
M Formel in einem String während Laufzeit berechnen. Allgemeine Java-Themen 4
KonradN Mal eine Frage zu Binary Serialization Allgemeine Java-Themen 15
D Hat Java eine Library um JavaScript auszuwerten? Allgemeine Java-Themen 2
dokan wie kann ich eine funktionierende Suchleiste erstellen Allgemeine Java-Themen 1
B Wie erstelle ich dazu eine Abfrage ob der Button gedrückt wurde? Allgemeine Java-Themen 8
J Integration pay Pale in eine JavaFx Desktop Application Allgemeine Java-Themen 1

Ähnliche Java Themen

Neue Themen


Oben