gpt4 book ai didi

java - Spring Boot bootJar mysql 驱动程序 impl 没有被 ServiceLoader 注入(inject)

转载 作者:行者123 更新时间:2023-12-01 17:06:38 25 4
gpt4 key购买 nike

所以我在运行 Spring Boot 的 gradle 任务 bootJar 生成的 jar 时遇到了一个非常奇怪的问题。我有一个在 mysql 数据库之上运行的 REST API,当前使用8.0.19 连接器,所以如果我运行 ./gradlew.sh bootRun 一切都很好,但如果我执行 ./gradlew.sh bootJar 生成 jar 然后运行它,有问题随着mysql驱动程序的加载,更准确地说,我得到java.lang.RuntimeException: Failed to get driver instance for jdbcUrl={myjdbcurl}

我做的第一件事是确保该 jar 具有包含在 BOOT-INF/lib 内的所有其他 jar 依赖项,并且那里一切正常。所以当我开始调试之后我注意到,由于某种原因,当执行 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 code> 这很好,但我不明白为什么找不到这个服务在运行 jar 期间,有什么想法如何找出原因和可能的修复方法吗?服务实现是否有可能被排除在 bootJar 或类似的东西之外?

最佳答案

好的,对于遇到同样问题的每个人,这里是解决方案:

我使用 HikariCP 作为数据源并定义我的配置

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

由于一些奇怪的原因,当我使用以下配置组装一个 jar 时,使用 ServiceLoader 的 DriverManager 找不到 META-INF/services 并且未注入(inject)实现,因此抛出了一个错误没有可用的驱动程序。如果我不以 JAR 形式启动应用程序 - 就不存在这样的问题。

所以要解决这个问题 - 只需添加 .config.setDriverClassName(yourDriverClass) - 它将隐式加载驱动程序,而不是依赖 ServiceLoader 来查找实现。然而,当从 jar 执行时,为什么 ServiceLoader 无法从 mysql.jar 找到 META-INF/services 仍然是一个谜。

关于java - Spring Boot bootJar mysql 驱动程序 impl 没有被 ServiceLoader 注入(inject),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61458737/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com