#java #mysql #postgresql #jdbc #jar
#java #mysql #postgresql #jdbc #jar
Вопрос:
Я пытаюсь поместить свой проект в JAR, чтобы я мог запустить его как CLI. У меня есть два JDBC-коннектора, которые я использую, один для MySQL, другой для PostgreSQL. Оба находятся в одном каталоге и отлично работают, если я запускаю их в IDE. Когда я создаю JAR, соединитель MySQL по-прежнему работает нормально, однако при попытке установить соединение с PostgreSQL появляется следующая ошибка. Что меня действительно раздражает, так это то, что соединитель, похоже, включен в сборку jar.
В сборке перечислены как соединитель MySQL, так и соединитель PostgreSQL. Как я могу это исправить?
Ответ №1:
Проблема в том, что все драйверы JDBC, совместимые с JDBC-4, содержат файл /META-INF/services/java.sql.Driver
, в котором перечислены java.sql.Driver
реализации в файлах JAR. Это используется java.sql.DriverManager
для загрузки доступных драйверов JDBC.
Процесс, который вы использовали для слияния, по-видимому, не объединяет разные файлы из драйверов в один файл, поэтому он содержит только содержимое одного из драйверов. В результате другой драйвер не загружается автоматически.
Возможные решения:
- Не объединяйте файлы JAR в один JAR, а вместо этого используйте
Class-Path
атрибутMETA-INF/MANIFEST.MF
для указания используемых вами JAR-файлов и выполняйте свою программу с помощьюjava -jar your.jar
- Убедитесь
META-INF/services/java.sql.Driver
, что он правильно объединен (или, возможно, предоставьте свой собственный), в зависимости от того, как вы объединяете, может быть возможность настроить, какие файлы необходимо объединить - Явно загрузите драйверы, используя
Class.forName("com.mysql.cj.jdbc.Driver")
иClass.forName("org.postgresql.Driver")
(сделайте это для обоих, чтобы предотвратить проблемы, если порядок слияния файлов изменится, а другой файл выиграет)
Комментарии:
1. Спасибо. Class.forName(«org.postgresql.Driver»); на самом деле сделал трюк.
2. @ChristianKammerer Да, но, как я уже упоминал, я рекомендую загружать оба драйвера явно, на случай, если в будущем слиянии будет использоваться другой порядок и
META-INF/services/java.sql.Driver
победит версия PostgreSQL вместо версии MySQL.3. Я не уверен, что полностью понимаю, но является ли это условием гонки, в которое загружается драйвер? Я вставил их оба для хорошей оценки, 😉
4. @ChristianKammerer Нет, речь идет о том, что вы создаете один JAR с содержимым нескольких JAR, и то, как вы объединяете эти JAR, не объединяет содержимое
META-INF/services/java.sql.Driver
файлов, которые существуют как в JAR MySQL Connector / J, так и в JAR PostgreSQL JDBC. Вместо этого он выбирает только содержимое одного файла (в данном случае из MySQL Connector / J). Итак, приDriverManager
обнаружении доступных драйверов JDBC он находит один файл определения службы, в котором указан только драйвер MySQL Connector / J.