CLASSPATH im Javaprogramm ändern

homer65

Top Contributor
Hallo Gemeinde,
ist es möglich in einem laufenden Javaprogramm den CLASSPATH zu ändern, so das der geänderte CLASSPATH auch für das laufende Programm genutzt wird? Und falls ja wie?
Hintergrund ist, das ich ein Javaprogramm mit Zugriff auf eine MySQL Datenbank schreiben möchte. Allerdings erfahre ich erst zur Laufzeit, wo sich der JDBC Treiber befindet. Dummerweise weiss ich es beim Start des Programms noch nicht.
Viele liebe Grüße Christian
 

HoaX

Top Contributor
Den Classpath direkt kannst du nicht ändern, und falls es doch über irgendwelche Tricks geht würde ich es nicht machen. Sinnvoller dürfte es ein den URLClassLoader zu verwenden um das Jar des Treibers zu laden und dann gezielt selbst den Treiber zu instanziieren, anstatt über den DriverManager.
 
D

DummyDriver

Gast
@Empire@Work
Wenn man z.B. einen Datenbank-Manager schreibt der mit mehreren Datenbanken arbeiten können soll, man aber erst nach Start der App den Driver auswählen kann.

@TO
JA, man kann den System-ClassLoader "hacken" da dieser auch nur eine Instanz von URLClassLoader ist und man so mit Reflections addURL() callen kann. Was aber zur Problemlösung nicht viel beitragen wird.

Da du schreibst du möchtest zur Runtime einen JDBC-Driver laden sag ichs dir leiber gleich : mit URLClassLoader wirst du nicht sehr weit kommen.

Grund : JDBC-Driver verwenden die ServiceLoader-API um beim Start der VM bereits geladen zu sein. Darum muss man auch dieses [c]Class.forName()[/c] nur bei denen machen die die ServiceLoader-API nicht nutzen, und das sind mitlerweile nur noch sehr wenige.
Was aber eher das Problem ist das wenn du z.B. den MySQL/J-Connector über einen URLClassLoader lädst dieser spätestens beim DriverManger.getConnection() eine Exception schmeißen wird. Warum das so ist kann ich dir auch nicht genau sagen, aber ich weis das gerade bei MySQL/J die Bedingung ist das dieser bereits zum Start der VM verfügbar sein muss.
Um dem zu entgehen kannst du nur mit einem "Dummy" tricksen. Dieser "Dummy" sieht dabei so aus (Java7 Version) :
Java:
import java.sql.*;
import java.util.*;
import java.util.logging.*;
public class DummyDriver implements Driver
{
	private Driver driver;
	private DummyDriver() { }
	public DummyDriver(Driver driver)
	{
		this.driver=driver;
	}
	public boolean acceptsURL(String url) throws SQLException { return driver.acceptsURL(url); }
	public Connection connect(String url, Properties info) throws SQLException { return driver.connect(url, info); }
	public int getMajorVersion() { return driver.getMajorVersion(); }
	public int getMinorVersion() { return driver.getMinorVersion(); }
	public Logger getParentLogger() throws SQLFeatureNotSupportedException { return driver.getParentLogger(); }
	public DriverPropertyInfo[] getPropertyInfo(String url, Properties info) throws SQLException { return driver.getPropertyInfo(url, info); }
	public boolean jdbcCompliant() { return driver.jdbcCompliant(); }
}
Für Java6 lässt du einfach "getParentLogger" weg.

Dadurch das DummyDriver bereits während des StartUp im ClassPath liegt hat die VM nun keine Probleme mehr damit über diese Klasse gekapselte Driver zu verwenden. Um nun aber deinen Driver beim DriverManager anzumelden kannst du dann diesen Code nutzen (mal als URLClassLoader-Variante) :
Java:
URLClassLoader cl=new URLClassLoader(new URL[] { new URL("/*absoluter Pfad zum Driver.jar*/") });
Driver driver=(Driver)cl.loadClass("/*voller Klassenname mit Package*/").newInstance();
DriverManager.registerDriver(new DummyDriver(driver));
Vorraussetzung für diese Methode ist natürlich das du den vollen Klassennamen des JDBC-Drivers kennst (also das was du sonst Class.forName()) übergeben würdest. Da wie oben gesagt mitlerweile fast alle die ServiceLoader-API verwenden kann man mit ZipFile/JarFile nach "/services/java.sql.Driver" suchen und den Inhalt lesen. Diesen setzt man dann bei loadClass() ein.

Ich weis das das ganze wie ein "Hack" aussieht, aber leider ist es nur so möglich (auch in Java7) einen JDBC-Driver zur Runtime zu laden. Wenn man es ohne diesen Dummy versucht wirft einem der Driver ne ganze Tonne an Exceptions (warum auch immer).

Der Grund warum ich das so genau weis ist weil ich mal das gleich Probleme hatte. Und das war die einzige Lösung.
 

homer65

Top Contributor
Dank des Hinweises von HoaX und Hilfe von:
Dynamic loading of JDBC drivers
(Durch googeln gefunden)
Funktioniert bei mir folgender Code tadellos:
[Java]
public Connection connect()
{
File file = new File(Parameter.jdbcdriver);
if (!file.canRead())
{
System.out.println("MySQL:connect:Can not read JDBC Driver:" + Parameter.jdbcdriver);
System.exit(12);
}
Connection erg = null;
try
{
URL u = file.toURI().toURL();
URLClassLoader ucl = new URLClassLoader(new URL[] { u });
Driver d = (Driver)Class.forName(Parameter.jdbcclass, true, ucl).newInstance();
DriverManager.registerDriver(new DriverShim(d));
erg = DriverManager.getConnection(Parameter.url,Parameter.userid,Parameter.password);
}
catch (Exception e)
{
erg = null;
System.out.println("MySQL:connect:Exception");
System.out.println(e.toString());
System.exit(8);
}
return erg;
}
[/Java]

Nochmals vielen Dank euch allen.
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
ExceptionOfExpectation Einsatz von CLASSPATH Allgemeine Java-Themen 30
L Jar Dateien in Classpath laden ab JDK 9+ Allgemeine Java-Themen 11
thet1983 Input/Output read properties file from classpath Allgemeine Java-Themen 3
F Classpath als Argument in Funktion übergeben Allgemeine Java-Themen 3
reibi Classpath Classpath Variable beim Tomcat Allgemeine Java-Themen 2
M Ant relative Pfade im Classpath vom Jar-Task Allgemeine Java-Themen 2
J Beanshell Classpath Reihenfolge Allgemeine Java-Themen 2
M Classpath und Buildpath Allgemeine Java-Themen 5
S .Classpath Datei im Eclipse Projekt Allgemeine Java-Themen 7
B Framework zum durchstöbern des classpath Allgemeine Java-Themen 2
reibi Files über Classpath laden Allgemeine Java-Themen 22
J Class.forName und CLASSPATH -Problem Allgemeine Java-Themen 5
S Eclipse und Glassfish Classpath-Fehler(?) Allgemeine Java-Themen 6
U Java file aus Classpath lesen Allgemeine Java-Themen 1
A AspectJ Compiler nicht im CLASSPATH? Allgemeine Java-Themen 4
A CLASSPATH unter Debian Lenny Allgemeine Java-Themen 4
Fadi Lade Klass(jar), die lib im classpath hat mit URLClassLoader Allgemeine Java-Themen 2
Escorter .jar Datei Classpath mitgeben ohne Dos Fenster Allgemeine Java-Themen 8
D Ordner mit *.properties in classpath ? Allgemeine Java-Themen 5
S Java 5/6 Problem im Classpath Allgemeine Java-Themen 11
P CLASSPATH LINUX Allgemeine Java-Themen 9
N Classpath mit ClassLoader künstlich erweitern Allgemeine Java-Themen 2
E In welcher Datei wird classpath gesetzt? Allgemeine Java-Themen 9
D Classpath setzten bei jogl (jsr-231) Allgemeine Java-Themen 2
S Java greif automatisch auf Classpath zu Allgemeine Java-Themen 2
V komischer ClassPath Allgemeine Java-Themen 6
M [Windows] Aufruf von Java mit Sonderzeichen im Classpath Allgemeine Java-Themen 5
T class file(s) on classpath not found or not accessible Allgemeine Java-Themen 8
A [SOLVED] Classpath und statische Variablen Allgemeine Java-Themen 6
G package und classpath grundsatzfrage Allgemeine Java-Themen 7
F suche im Classpath mit Pattern *.gif Allgemeine Java-Themen 16
P CLASSPATH und Jar Allgemeine Java-Themen 40
P Classpath, Tomcat und Eclipse Allgemeine Java-Themen 4
T Classpath per Java Programm setzen Allgemeine Java-Themen 9
D jdic classpath setzen Allgemeine Java-Themen 2
G Classpath Allgemeine Java-Themen 5
F mit getResourceAsStream () Datei im Classpath suchen Allgemeine Java-Themen 15
G Classpath, Packages und Import Allgemeine Java-Themen 3
G Classpath? Allgemeine Java-Themen 3
S Verständnis Problem - Classpath Allgemeine Java-Themen 5
G Classpath bei JAR Allgemeine Java-Themen 14
M Auf Klassen in jar-File (nicht im CLASSPATH) zugreifen Allgemeine Java-Themen 4
G Doppelklick auf Javaprogramm klapt nicht Allgemeine Java-Themen 1
J Aus JavaProgramm Setup Exe aufrufen Allgemeine Java-Themen 9
M Aus Javaprogramm .NET Quellcode kompileren Allgemeine Java-Themen 2
E Protokollierung zu Javaprogramm Allgemeine Java-Themen 5
A Javaprogramm als Windowsservice starten Allgemeine Java-Themen 4
L Javaprogramm als SoundIn Device Allgemeine Java-Themen 3
D ewig laufendes Javaprogramm ("Service") Allgemeine Java-Themen 17
T Javaprogramm unter Linux auf bestimmten Kern starten/laufen lassen ? Allgemeine Java-Themen 22
M Maus durch JavaProgramm bewegen Allgemeine Java-Themen 2
G Javaprogramm ohne Java Allgemeine Java-Themen 24
B Javaprogramm als Dienst mit Netzwerkzugriff? Allgemeine Java-Themen 5
F JavaProgramm mit der Tastatur Steuern Allgemeine Java-Themen 3
J Javaprogramm ueber Windowskontextmenue starten Allgemeine Java-Themen 2
V JavaProgramm von Konsole starten geht nichtmehr Allgemeine Java-Themen 4
K Zugriff von Javaprogramm auf Worddoku Allgemeine Java-Themen 2
C Javaprogramm von außen steuern? z.b mit VB Allgemeine Java-Themen 11
S Javaprogramm lässt sich nicht per .bat Datei ausführen. Allgemeine Java-Themen 22
R Javaprogramm von der Konsole starten Allgemeine Java-Themen 4
P Javaprogramm soll doppeltgeklickte Datei verarbeiten Allgemeine Java-Themen 22
b3ny javaprogramm als windows anwendung compilieren Allgemeine Java-Themen 9
torresbig Klasse mit extends Calendar über Methoden ändern (Hirnblockade) Allgemeine Java-Themen 7
B Liste ändern während Iteration über Diese? Allgemeine Java-Themen 16
N Fahrtrichtung eines selbstfahrenden Auto ändern Allgemeine Java-Themen 3
Z Java Testklassenvariable ändern im Hauptprogramm Allgemeine Java-Themen 5
L Uhrzeit von 24-Uhr zu 12-Uhr ändern Allgemeine Java-Themen 2
Thallius Zeitzone zu einem LocalDate hinzufügen aber ohne es zu ändern... Allgemeine Java-Themen 2
N Speicherort einer Datei im Explorer ändern Allgemeine Java-Themen 8
W Classpath Reflexion - Prüfen ob man auf ein Feld ändern kann Allgemeine Java-Themen 2
J Jasper Reports - Subreport zur Laufzeit ändern Allgemeine Java-Themen 6
N Variablen Array Länge ändern. Allgemeine Java-Themen 8
R Methoden Was fehlt mir bzw. muss ich bei der Methode countHarshabNumbers ändern damit ich die Harshad Zahlen im Intervall [51, 79] zählen kann? Allgemeine Java-Themen 19
R Was muss ich ändern, damit der Kreis links unten gezeichnet wird? Allgemeine Java-Themen 17
L Hintergrundfarbe jedes spinner-Elements ändern Allgemeine Java-Themen 1
Q Eclipse Escape Sequenzen Farbe ändern Allgemeine Java-Themen 4
OSchriever Einfach verkettete Liste ändern Allgemeine Java-Themen 43
D Boolean von ein anderem Java Programm während der Laufzeit ändern Allgemeine Java-Themen 23
D ArrayList Indexlänge ändern Allgemeine Java-Themen 2
E javax.mail sene Type ändern Allgemeine Java-Themen 2
J Farbe von Buttons mehrmals ändern Allgemeine Java-Themen 5
B Übernommene Variablen(werte) aus der Main-Klasse ändern? Allgemeine Java-Themen 9
B ImageView Farbe ändern Allgemeine Java-Themen 3
J Eine bestimmte Zahl im Integer ändern Allgemeine Java-Themen 9
T ändern neue Java Versionen was an der Programmiersprache? Allgemeine Java-Themen 15
R Zeitformat ändern Allgemeine Java-Themen 18
olfibits Erste Schritte Konsolentitel ändern Allgemeine Java-Themen 3
R Variable durch mehrere Methoden ändern und nutzen Allgemeine Java-Themen 17
S Kann man mit Java auf einem lokalen PC/Mac Benutzergruppen auslesen und Rechte ändern? Allgemeine Java-Themen 11
N Das Ende von bestimmten zeilen in text datei ändern und speichern Allgemeine Java-Themen 3
B Input/Output Datei ändern Allgemeine Java-Themen 9
T JasperReport Hintergrundfarbe wertabhängig ändern Allgemeine Java-Themen 3
sandaime CMD aufrufen und aktuellen pfad ändern Allgemeine Java-Themen 11
M Variable ändern bei jedem Schleifendurchlauf Allgemeine Java-Themen 32
RalleYTN DPI eines Bildes ändern Allgemeine Java-Themen 4
K eclipse Workspace ändern Allgemeine Java-Themen 2
J Properties file ändern Allgemeine Java-Themen 12
R WebDriver Firefox preferences ändern Allgemeine Java-Themen 0
W Input/Output Kann .properties Datei in kompilierter .jar nicht ändern Allgemeine Java-Themen 2
G Unix Passwort mit Java ändern? Allgemeine Java-Themen 3

Ähnliche Java Themen

Neue Themen


Oben