2009-08-26 13 views
2

Ich arbeite an einem kleinen Java-Projekt, das jetzt mit einer MS SQL Server 2000-Datenbank verbindet, wird aber in Kürze eine Verbindung zu MS SQL Server 2005-Datenbank herstellen. Ich erstelle ein einzelnes Glas für die einfache Bereitstellung. Ich habe versucht, es einzurichten, so dass ich einfach eine Konfigurationsdatei ändern und Treiber ändern konnte (wie in .NET). Aufgrund der Einschränkungen von Javas Jar embedded classpath und dem Fehlen des Platzhalterzeichens auf dem eingebetteten Klassenpfad (1). Gibt es eine Möglichkeit, dieses Problem zu umgehen, ohne explizit auf jeden Treiber-Jar zu verweisen? Wenn ich das tun muss, muss ich jedes Mal neu kompilieren, wenn sich die Datenbank ändert ...Jar Dateiabhängigkeiten in Java 1.4

(1): Allerdings werden Klassenpfad-Platzhalter im Klassenpfad-JAR-Manifestheader nicht berücksichtigt.

+0

Ihr Link ist zu Java 6. In 1.4 gab es überhaupt keine Klassenpfad-Platzhalter. – Yishai

+0

Ich weiß, noch besser! –

Antwort

2

Im Allgemeinen können Sie die classpath at runtime ändern. Ansätze wie diese sind der generelle Weg, um mit "plugin" -artigen Jars in Java umzugehen (sehr ähnliche Anforderungen an Ihren Fall).

0

Sie könnten Informationen über den zu verwendenden Treiber z. eine Konfigurationsdatei Oder im Manifest der JAR-Datei selbst. Geben Sie beim Starten der Anwendung einfach alle JAR-Dateien ein, laden Sie den Namen des Treibers jedoch aus der Konfiguration.

0

Ich würde sagen, dass es nicht der Java-Weg (wie in der Standard-Praxis) ist, Code von Drittanbietern in das gleiche Jar zu integrieren, wie Sie es bereitstellen. Ein Jar ist jedoch nur eine Zip-Datei, daher können Sie diese in den meisten Fällen (mit Ausnahme einiger schicker Dinge, die in den Manifesten vorkommen) beliebig kombinieren.

Das heißt, Sie können in Ihre JAR-Datei eine Klassenpfad-Referenz zu allen möglichen JDBC-Treiber-JARs aufnehmen oder einfach den JDBC-Treiber JAR auf die richtige Weise aufrufen. Dann haben Sie eine Konfigurationsdatei im selben Verzeichnis (stellen Sie sicher, dass Sie. Im Klassenpfad Ihrer JAR einbeziehen) und lesen Sie dann den Treibernamen und verwenden Sie Class.forName(), um den Treiber zu laden.

Sie können zärtere Dinge tun (wie zum Beispiel das richtige jar zur Laufzeit finden und es dynamisch laden, obwohl es nicht auf dem Klassenpfad war), aber diese Dinge sind ein bisschen kompliziert, also sollte etwas einfaches wie oben beschrieben funktionieren.

Sie sollten nie neu kompilieren müssen. Sie tun JDBC nicht wirklich richtig, wenn Sie neu kompilieren müssen, wenn Sie Treiber ändern.

+0

Kann ich Class.ForName() für eine Klasse ausführen, die sich in einem Jar befindet, das sich nicht in meinem ClassPath befindet? Wenn nicht, dann bin ich immer noch auf die Jars beschränkt, die speziell im Classpath aufgelistet sind, und muss immer noch neu kompilieren (re-jar?), Wenn ein neues Treiberjar erscheint. –

+0

Der Class.forName muss in der Klassenpfadlaufzeit enthalten sein. Keine Notwendigkeit, neu zu kompilieren. Wenn ein neues jar ausgegeben wird, ersetzen Sie einfach die Datei und müssen nicht neu kompiliert werden. – Yishai

+0

Microsoft hat eine wunderbare Angewohnheit, ihre Treiber-JAR-Dateien anders zu benennen. –

0

Sie müssen die Treiber-JAR-Datei und den tatsächlichen Namen des JDBC-Treibers für den jeweiligen Provider trennen.

Ich würde wirklich ermutigen, jdbc Treibergläser nicht in Ihr eigenes Glas einzuschließen. Nur bei ihnen auf den Pfad zur Laufzeit. In ähnlicher Weise können Sie den Namen des JDBC-Treibermanagers während der Laufzeit aus den Systemeigenschaften oder sogar eine Konfigurationsdatei abrufen.

So läuft App wie folgt aus:

java -jar myapp.jar -cp sqlserver.jar -DdriverManager=com.microsoft.sqlserver.jdbc.SQLServerDriver -DdbUrl=jdbc:some:url 

und in der Anwendung, so etwas tun (ich auslassen Ausnahmebehandlung):

Class.forName(System.getProperty("driverManager")); 
Connection conn = DriverManager.getConnection(System.getProperty("dbUrl")) 

;

Auf diese Weise können Sie Treiber einfach ändern, indem Sie dem Klassenpfad die entsprechende JAR-Datei hinzufügen und die Eigenschaften driverManager und dbUrl ändern. Auf diese Weise müssen Sie nicht neu kompilieren, um neue Treiber zu unterstützen.

Das ist die einfachste Lösung, die ich mir vorstellen kann.

+0

Kann ich Class.ForName() für eine Klasse ausführen, die sich in einem Jar befindet, das sich nicht in meinem ClassPath befindet? Wenn nicht, dann bin ich immer noch auf die Jars beschränkt, die speziell im Classpath aufgelistet sind, und muss immer noch neu kompilieren (re-jar?), Wenn ein neues Treiberjar erscheint. –

+0

In Class.forName() geben Sie eine Zeichenfolge ein, sodass Sie dort beliebige Elemente einfügen und eine Ausnahme abfangen können, um festzustellen, ob etwas gefunden wurde. ABER. Warum möchten Sie Class.forName() hardcodieren? Die obige Lösung ermöglicht es Ihnen, sie zur Laufzeit zu ändern, so dass Ihre Anwendung jede Datenbank unterstützen kann, solange der richtige Treibermanager und die richtige db-URL angegeben sind (und ein jar mit Datenbanktreiber im Klassenpfad ist). –