Classpath Programmteile zur Laufzeit nachladen

  • Themenstarter Themenstarter Firephoenix
  • Beginndatum Beginndatum
F

Firephoenix

Gast
Hi, mir ist kein besserer Titel eingefallen...

Folgendes Problem:
Ich habe eine Grundapplikation die ganz grob gesagt dazu dient Instanzen eines bestimmten Interfaces auszuführen (nennen wir es hier mal Interface A).

Ich will (bzw muss) in der Lage sein konkrete Implementierungen zur Laufzeit "nachladen" zu können und diese zu benutzen.
Dazu bekomme ich ein Bundle aus .jar-Files:
einmal das eigentliche Programm "P" in dem irgendwo eine .class rumfliegt die A implementiert
und weiterhin alle libs von denen "P" abhängt (z.b. logger, netwerklibs, könnte alles sein).
(Wenn ich viel Glück habe evtl noch den konkreten Klassennamen der A implementiert, darauf habe ich aber keine Garantie - es ist aber unwahrscheinlich das in einem einzubindenden Projekt mehr als eine Klasse vorhanden ist die A implementiert).
Ich muss jetzt irgendwie an die .class herankommen die A implementiert (ebenfalls keine Garantie darauf dass auch der Source verfügbar ist), diese instanzieren und dann eine parametrisierte Methode des Interfaces A auf diesem Objekt aufrufen die das zu ladende Programm startet (und die dann ggf. auch abhängige Methoden der zusätzlichen .jar-Files benötigt).
Weiterhin ist es möglich das mehrere der zu ladenden Programme gleiche Abhängigkeiten haben, oder Abhängigkeiten die bereits im Classpath der Grundapplikation vorhanden sind (klassisches Beispiel: slf4j).

Änderungen der gegebenen Programme ist nicht möglich, das Maximum wäre wohl eine Zusatzdatei die den Pfad der Klasse angibt die A implementiert.
(Sowas wie xyz.jar - package.a.b.c.d.Feature.class)

Gibt es dafür irgendwelche eleganten Möglichkeiten? Ich bin in dem Gebiet leider alles andere als fit :rtfm:.

Gruß
 
habe das mal so gelöst:

Java:
public class Test
{
	public static void main(String[] args)
	{			
			InterfaceA a = null;
			File file = new File("pfad/"+namederjar+".jar");
			Class<?> driverClazz = null	;
			URLClassLoader ucl = getClassLoader(file);
			try
			{		
			 driverClazz = ucl.loadClass("package.AImpl");// könnte auch als Parameter var...
			 a = (InterfaceA)driverClazz.newInstance();		
			}
			Exceptions...
			...
			...			
			a.start(); //z.B.		
	}

	private static  URLClassLoader getClassLoader(File file) 
	{	
		URLClassLoader ucl = null;
		try
		{
			ucl = new URLClassLoader(new URL[] { file.toURI().toURL() });
		}
		catch (MalformedURLException e)
		{	
			e.printStackTrace();
		}		
		return ucl;
	}	
}
 
Zuletzt bearbeitet:
@Tomate_Salat
Mit osgi müsste ich aber meine grunddaten anpassen oder?

@parabool
Mit der Version könnte ich einzelne Klassen instanzieren, das war mir bekannt. Das Hauptproblem sind aber die zusätzlichen Dependencies die die Module mitbringen.

Trotzdem danke schonmal für die Antworten 🙂

Gruß
 
Man kann doch mittlerweile Ordner mit Wildcards angeben von denen die Jars geladen werden (Setting the class path "Understanding class path wildcards"), damit sollten sich die Dependencies auf einen Schlag laden lassen.

Probleme wird es geben, sobald es etwas komplexer wird, speziell ClassLoader Probleme.
 
Die osgi-Umstellung ist mit meinen Vorgaben leider nicht umsetzbar (auch wenn das mein persönlicher Favorit wäre), die classpath-Erweiterung werde ich auf alle Fälle mal genauer anschauen, evtl kann ich die Anforderung so biegen das der User seine Implementierung + Zusatzlibs vor dem Start in ein Verzeichnis einfügen muss (oder ihm ein tool dafür anbieten um das zu Integrieren).
 

Zurück
Oben