2013-02-20 2 views
3

Я пытаюсь построить проект в clojure, который берет данные из базы данных Microsoft SQL Server и выталкивает его в базу данных MySQL.Создание uberjar для проекта, который использует MySQL и SQLServer

Проект работает нормально, используя LEIN бег, но когда я упаковать его в uberjar использованием Leiningen, и запустить его с помощью Java -jar, он терпит неудачу с:

Исключение в нити «главного» Java. sql.SQLException: Нет подходящий драйвер найден для JDBC: SQLServer ....

Эта ошибка происходит только тогда, когда я пытаюсь использовать как базу данных MySQL и базы данных SQL Server. Если я использую любой из них сам по себе, файл jar работает отлично, используя java -jar.

Мой project.clj выглядит следующим образом:

(defproject sqlserver-clojure "1.0.0-SNAPSHOT" 
    :description "A minimal example of the MySQL/SQLServer conflict" 
    :dependencies [[org.clojure/clojure "1.4.0"] 
      [com.microsoft/sqljdbc4 "3.0"] 
      [clojureql "1.0.4"] 
      [mysql/mysql-connector-java "5.1.6"]] 
    :main sqlserverclojure.core) 
+3

Убер-банки - это зло; вы, вероятно, не копируете определенные ресурсы или записи в «META-INF» или, что хуже их переписываете (например, «META-INF/services/java.sql.Driver» существует во всех совместимых с JDBC драйверах с различным контентом) –

+0

Вы можете всегда возвращайтесь к «классическому» методу загрузки драйверов JDBC с использованием 'Class.forName (« driver.class.Name »)' где-то в вашем приложении перед использованием JDBC. В качестве альтернативы вы можете использовать объекты DataSource вместо 'DriverManager.getConnection()' – millimoose

+0

@millimoose Упоминание 'META-INF/services/java.sql.«Драйвер» был всего лишь примером, загрузка драйвера все равно может потерпеть неудачу (даже при использовании классического метода или «DataSource»), например, потому что другие требуемые ресурсы не были скопированы. –

ответ

2

Проблема заключается в том, что, скорее всего, при создании убер-банку, вы не скопировать некоторые файлы (например, .properties или XML конфигурации), которые необходимы драйвер, или вы переписываете файлы, которые существуют в обоих драйверах JDBC.

Хорошим примером перезаписи является файл META-INF/services/java.sql.Driver, который есть у всех драйверов JDBC 4. Этот файл содержит список всех классов в банке, реализующих java.sql.Driver, так что класс java.sqlDriverManager может автоматически загружать все реализации Драйвера с использованием ServiceLoader.

Если вы создаете uber-jar с несколькими драйверами JDBC, вам необходимо либо убедиться, что этот файл содержит объединение всех этих файлов, либо ваше приложение должно явно загружать необходимые драйверы с помощью Class.forName("<name of the java.sql.Driver implementation>") для каждого требуемого драйвера и не зависят от автозагрузки драйвера JDBC 4.

Также убедитесь, что процесс, который вы используете для создания копий uber-jar, все ресурсы, а не только .class файлов!

еще лучше (на мой взгляд), не используйте убер-банку, но сохранить зависимые .jar файлы внешних и ссылаться на них в Class-Path вступления META-INF/MANIFEST.MF файла вашего приложения, это экономит вам много хлопот чтобы ваша uber-jar работала правильно (или убедитесь, что она действительно работает правильно).

+0

Отличное объяснение ... но знаете ли вы, что можно исправить в будущих версиях лейна? (можно ли даже исправить?) – joefromct

+0

@joefromct Простейшим решением является не создание uber-jar, а ссылка на необходимые библиотеки в манифесте. Я не знаю, есть ли решения, которые затрагивают все эти проблемы при объединении библиотек в одну банку, потому что я никогда не делаю этого сам. Технически можно было бы решить большинство этих проблем слияния, за исключением, может быть, конфигурационных файлов с одинаковыми именами, которые нельзя объединить. –

1

Добавление этого для моей собственной ссылки, поскольку я до этого не касался Java и не работал с Java-взаимодействием.

Добавить

(. Class (forName "com.microsoft.sqlserver.jdbc.SQLServerDriver")) 

В пространстве имен с вызовами функции Clojure JDBC.