Драйвер Spring Boot bootJar mysql подразумевает, что ServiceLoader не внедряется - PullRequest
0 голосов
/ 27 апреля 2020

, поэтому у меня действительно странная проблема с запуском jar-файла, созданного загрузочной задачей Spring Boot bootJar. У меня есть REST API, который работает поверх базы данных mysql, в настоящее время использует соединитель 8.0.19, поэтому, если я запускаю ./gradlew.sh bootRun, все в порядке, но если я делаю ./gradlew.sh bootJar, чтобы сгенерировать jar, а затем запустить его, там проблема с загрузкой драйвера mysql, точнее получаю java.lang.RuntimeException: Failed to get driver instance for jdbcUrl={myjdbcurl}.

Первое, что я сделал, - убедился, что в jar есть все другие зависимости jar, включенные в BOOT-INF/lib, и там все в порядке. Поэтому после начала отладки я заметил, что по какой-то причине при выполнении bootRun драйвер регистрируется, но во время bootJar - нет. Итак, чтобы сузить круг вопросов, я дошел до того, что DriverManager фактически регистрирует драйверы, и заметил, что во время работы jar следующие строки

ServiceLoader<Driver> loadedDrivers = ServiceLoader.load(Driver.class);
Iterator<Driver> driversIterator = loadedDrivers.iterator();

не возвращают реализацию сервиса для драйвера, (и они верните конкретный импл при запуске во время bootRun). Определение драйвера - /mysql-connector-java-8.0.19.jar!/META-INF/services/java.sql.Driver, где класс - com.mysql.cj.jdbc.Driver, что хорошо, но я не понимаю, почему этот сервис не найден во время работы фляги, какие-либо идеи, как выяснить причину и возможное исправление ? Есть ли вероятность, что служба impl может быть исключена из bootJar или что-то подобное?

1 Ответ

0 голосов
/ 29 апреля 2020

Ладно, для всех, у кого такая же проблема, вот решение:

Я использовал HikariCP в качестве источника данных и определял свой конфиг

    config.setPoolName(metadata.getPoolName());
    config.setJdbcUrl(metadata.getJDBCUrl());
    config.setUsername(metadata.getUsername());
    config.setPassword(metadata.getPassword());
    config.setMaximumPoolSize(poolSize);

по какой-то странной причине, когда Я собираю jar со следующей конфигурацией DriverManager, который использует ServiceLoader, не находит META-INF / services, и реализация не вводится, поэтому была выдана ошибка, что нет доступного драйвера. Если я запускаю приложение не как JAR - такой проблемы нет.

, чтобы решить эту проблему - просто добавьте .config.setDriverClassName(yourDriverClass) - она ​​будет неявно загружать драйвер, а не полагаться на ServiceLoader, чтобы найти импл , Однако до сих пор остается загадкой, почему ServiceLoader не может найти META-INF / services из mysql .jar, когда выполняется из jar.

...