jar-Files, Bibliotheken nachladen

wolfclaw

Grünschnabel
Hallo!

Ich habe folgende Frage: Ist es möglich im laufenden Betrieb (Anwendung wurde bereits gestartet und läuft) jar-Files nachzuladen, also das im Code zu managen.

Hab mir das so gedacht:
Es gibt einen Java Server als Basisframework der jederzeit dynamische Module nachladen kann. Das soll so funktionieren, dass der Server ein jar-File bekommt (ein neues Modul), dieses lädt und in den laufenden Betrieb integriert.

Viele Grüße,

Wolfclaw
 
Moin!
Mit einem Klassenlader kannst du die neuen Module laden. Schau dir dazu zum Beispiel mal den URLClassLoader an:
http://java.sun.com/j2se/1.4.2/docs/api/java/net/URLClassLoader.html

Und über Reflection kannst du dann dir dann Instanzen der benötigten Klassen erstellen..

Skizze:
Code:
URL[] urls = new URL[1];
File jar = new File("jarfile.jar");
urls[0] = jarfile.toURL();
URLClassLoader loader = URLClassLoader.newInstance(urls,ClassLoader.getSystemClassLoader());
Object instanceOfClassName = loader.loadClass("ClassName",true).newInstance();

*grüssle*
MeinerEiner
 
Huhu,

ich hab da mal anhand von Modulen ein Beispiel bebastelt welches mit zwei JAR Dateien funktioniert. (zwei Projekte)

Die erste JAR Datei nennt sich ModuleManager.jar, welche das Laden der verschiedenen Module (jar dateien) übernimmt und zudem bereits ein fertiges Modul enthält. Dieses Projekt/Jar enthält folgende Klassen und Interfaces:

com.test.Module
Java:
package com.test;

public interface Module {

	public String getModuleName();
	
}

com.test.ModuleOne
Java:
package com.test;


public class ModuleOne 
	implements Module {

	public String getModuleName() {
		return "ModuleOne Version 1.0";
	}

}

com.test.Main
Java:
package com.test;

import java.io.File;
import java.net.URL;
import java.net.URLClassLoader;

/**
 * 
 * @author M.Freiholz / Gainwar
 *
 */
public class Main {

	public static void main(String[] args) {

		// --
		// Module 1 - Already in class path.
		// Try to create module-1 which is already in class path.
		String m1class = "com.test.module.ModuleOne";
		try {
			
			// Dynamic class instance.
			Class clazz = Main.class.getClassLoader().loadClass( m1class );
			Module moduleOne = ( Module ) clazz.newInstance();
			
			// Call the 'getModuleName' method of Module, to find out
			// which class/module we have on hand.
			System.out.println( moduleOne.getModuleName() );
			
		}
		catch( Exception e ) {
			e.printStackTrace();
		}
		
		// --
		// Module 2 - Not in classpath.
		// Cause the ModuleTwo-Class is not in classpath, we have to load the class.
		String m2class = "com.test.module.ModuleTwo";
		File pathToJarFile = new File( "C:/testumgebung/nachladen/module2.jar" );
		try {
			
			// Create a new URLClassLoader, which loads the JAR file with all
			// classes.
			URL[] urls = new URL[] { pathToJarFile.toURL() };
			URLClassLoader cl = new URLClassLoader( urls );
			
			// Load the class from the above created URLClassLoader.
			Class clazz = cl.loadClass( m2class );
			Module moduleTwo = ( Module ) clazz.newInstance();
			
			// Call the 'getModuleName' method of Module, to find out
			// which class/module we have on hand.
			System.out.println( moduleTwo.getModuleName() );
			
		}
		catch( Exception e ) {
			e.printStackTrace();
		}
		
	}

}

Ab hier kann die Methode main(..) schon ausgeführt werden. Es wird die Rückgabe des Modules 1 geben und anschließend eine Exception weil com.test.module.ModuleTwo nicht gefunden werden kann. Ist ja nur logisch, schließlich existiert es noch nicht.

Das zweite Modul wird nun in eine seperate JAR Datei gesteckt und sieht wie folgt aus:

com.test.module.ModuleTwo
Java:
package com.test.module;

import com.test.Module;

public class ModuleTwo
	implements Module {

	public String getModuleName() {
		return "ModuleTwo Version 0.1a";
	}

}

Die JAR Datei welche das zweite Modul beinhaltet kann nun an einen beliebigen Ort auf der Festplatte kopiert werden. Jetzt muss nur darauf geachtet werden in der vorhin erstellten Klasse com.test.Main auch den Pfad zu dieser JAR Datei zu ergänzen.

Wenn nun die main(...) Methode ausgeführt wird, sollte folgende Ausgabe erscheinen:

Code:
ModuleOne Version 1.0
ModuleTwo Version 0.1a

Im Anhang befindet sich noch ein Screenshot, damit die Struktur evtl. ein bisschen klarer ist.
Hoffe ich hab mich verständlich genug ausgedrückt :)

Gruß Manuel
 

Anhänge

  • struktur.jpg
    struktur.jpg
    14,2 KB · Aufrufe: 57
Eine Frage habe ich noch:

Angenommen das bereits geladene jar-File wird erneuert/verändert und ich benutze wieder den beschriebenen Code, wird dann das jar-File neu geladen oder muss ich das alte erst wieder entfernen und das neue laden (falls das geht)?
 
Zurück