JAR-Dateien statisch laden?

Thomas Kuse

Erfahrenes Mitglied
Hallo!

Wie kann man abhängige JAR-Dateien beim Start des Javaprogramms statisch, also komplett, laden lassen (für Win32).
Im Normalfall werden die abhängigen JAR-Dateien mit einem File-Lock versehen und werden dann bei Bedarf nachgeladen.

Mein Problem ist, dass aktuell laufende Java-Programme im Hintergrund aktualisiert werden dürfen. Das ist aber durch das dynamische Laden der Klassen und dem File-Lock nicht möglich, da keine Schreibrechte vorhanden sind.

Ich habe jetzt ein C-Programm geschrieben, welches den File-Lock durch einen Trick im Win32-Prozess- und FileHandle-System entfernt. Jedoch ist das gerade geöffnete Java-Programm nicht mehr lauffähig, wenn es benötigte Klassen nachladen muss und der FileHandle auf diese nicht mehr existiert.

Vielleicht kennt ja jemand einen Kommandozeilenparameter für javaw.exe (-staticloadlibraries wär doch toll).

Danke!
 
Hallo Thomas,
schön mal wieder was von Dir zu lesen :)

ich denke was du brauchst ist eine Art "vernünftiger" Plugin Mechanismus und keine low level Klempnerei ;-)
Schau doch mal hier:
http://www.osgi.org/
Das ist das Framework mit dem Eclipse 3.x den Plugin (Bundle)-Mechanismus realisiert. (Genauergesagt ist es das Unterproject Equinox welches den OSGI Mechanismus implementiert: http://www.eclipse.org/equinox/)
Eine weitere Anwendung / Implementierung wäre Knoplerfish:
http://www.knopflerfish.org/

Oder baue deine Anwendung doch gleich auf der Eclipse Platform auf :)

Weiterhin schau mal hier:
http://javangelist.snipsnap.org/space/Plugin

und hier:
https://jplugin.dev.java.net/
(Brauch wohl noch ein wenig zur Reife...)

Man könnte sich sowas auch selber bauen, das wäre aber mitunter sehr aufwendig...

Gruß Tom
 
Hallo Tom! :)

Danke für deine Tips, aber ich hätte gedacht es gibt Programm-Start-Argumente für die java.exe oder sowas, denn das Verfahren was ich da beschrieben habe, soll für alle 300 - 500 java-Programme in meiner Firma funktionieren ... für alte und neue, ohne dass deren Code neu übersetzt oder gar angepasst werden muss.

dank dir trotzdem, die links sind alle sehr interessant !

gruss aus Berlin
 
Tom hat diesen Link gepostet, dabei bin ich ueber Groovy gestolpert. Ohne mich da jetzt tief eingelesen zu haben, denke ich dennoch, dass das vielleicht eine Loesung fuer dein Problem sein koennte:
Groovy can be used as an alternative compiler to javac to generate standard Java bytecode to be used by any Java project or it can be used dynamically as an alternative language such as for scripting Java objects
Groovy can be used as an embedded language for dynamic business rules or extension points utilizing the agility of Groovy and saving the cost of redeploying applications for each change of rule

Moeglicherweise kannst du das statische Laden damit erreichen.

HTH
DH
 
Hallo!

Löschen kann man eine verwendet jar Bibliothek im ClassPath zwar nicht, aber man kann sie mit einer neuen Version überschreiben ;-)
(Dies ist dann natürlich mehr ein Hack als eine Lösung, denn was passiert, wenn das jar gerade dann überschrieben wird, wenn der ClassLoader versucht darauf zuzugreifen... hier müsste man sich dann noch entsprechende Locking-Mechanismen überlegen)

Code:
   /**
    * 
    */
   package de.tutorials;
   
   import java.io.File;
   import java.net.URL;
   import java.net.URLClassLoader;
   
   /**
    * @author Tom
    * 
    */
   public class ClassLoadingExample {
   
   	/**
   	 * @param args
   	 */
   	public static void main(String[] args) {
   		try {
   			while (true) {
 				ClassLoader classLoader = URLClassLoader
 		 		 .newInstance(new URL[] { new File("c:/test/foo.jar")
 		 		 		.toURL() });
 				Runnable foo = (Runnable) classLoader.loadClass(
 		 		 "de.tutorials.Action").newInstance();
   				foo.run();
   
   				Thread.sleep(10000L);
   			}
   
   		} catch (Exception e) {
   			e.printStackTrace();
   		}
   	}
   }

Action:
Code:
   package de.tutorials;
   
   public class Action implements Runnable {
   	public void run() {
   		System.out.println("action A");
   	}
   }
Wenn du die Klasse de.tutorials.Action aus einem anderen Eclipse Projekt in das test.jar exportierst kannst du sehen, dass beim nächsten Ausführen der run() Methode
die neue Klasse gezogen wird.

Wenn man diesen Weg geht wird man jedoch sehr bald mit recht umständlicher ClassLoader fummelei konfrontiert. Hier sollte man überlegen, ob man den Aufwand betreibt dafür eine Lösung zu finden (ist möglich...) oder man verwendet die schon vorhandenen Plugin-Frameworks.

Gruß Tom
 
Mal ganz dumm gefragt: Wiso ist ein Plugin Framework dazu in der Lage?
Wenn ich dich richtig verstehe, schlägst du vor, Eclipse oder etwas vergleichbares einzusetzen, also die Anwendung quasi in Eclipse laufen zu lassen. Was verändert sich dadurch für den Entwickler? Wiso kann man dadurch das Verhalten von Java zur Laufzeit derart beeinflussen?

Finde das sehr interessant, bitte um Aufklärung.

Gruss,
DH
 
Hallo!

Das was Thomas eigentlich gerne haette waere eine Update-Funktion. Anwendungen die auf der Eclipse Rich Client Platform basieren koennen gleich auch den Update Mechanismus (Update-Sites) von Eclipse wiederverwenden. Um dabei die Anwendung in einzelne Teile zu Zerlegen, die dann voneinander seperat geupdated werden koennen bieten sich Eclipse / OSGI Plugins/Bundles an :)

Gruss Tom
 

Neue Beiträge

Zurück