【问题标题】:No suitable driver found when exporting to a JAR-file?导出到 JAR 文件时找不到合适的驱动程序?
【发布时间】:2021-05-20 15:42:27
【问题描述】:

我正在尝试将我的项目放入 JAR 中,以便可以将其作为 CLI 运行。 我正在使用两个 JDBC 连接器,一个用于 MySQL,一个用于 PostgreSQL。如果我在 IDE 中运行它们,它们都位于同一个目录中并且可以正常工作。 当我创建 JAR 时,MySQL 连接器仍然可以正常工作,但是当尝试建立与 PostgreSQL 的连接时,会出现以下错误。 真正让我恼火的是连接器似乎包含在 jar 的构建中。 MySQL 连接器和 PostgreSQL 连接器都在构建中列出。 我该如何解决这个问题?

【问题讨论】:

    标签: java mysql postgresql jdbc jar


    【解决方案1】:

    问题在于所有符合 JDBC-4 的 JDBC 驱动程序都包含一个文件 /META-INF/services/java.sql.Driver,其中列出了 JAR 文件中的 java.sql.Driver 实现。 java.sql.DriverManager 使用它来加载可用的 JDBC 驱动程序。

    您用于合并的过程显然不会将驱动程序中的不同文件合并到一个文件中,因此它只有一个驱动程序的内容。因此,不会自动加载其他驱动程序。

    可能的解决方案:

    1. 不要将 JAR 文件合并到单个 JAR 中,而是使用 META-INF/MANIFEST.MFClass-Path 属性来指定您使用的 JAR,并使用 java -jar your.jar 执行您的程序
    2. 确保META-INF/services/java.sql.Driver 已正确合并(或者可能提供您自己的),根据您的合并方式,可能会有一个选项来配置需要合并的文件
    3. 使用Class.forName("com.mysql.cj.jdbc.Driver")Class.forName("org.postgresql.Driver") 显式加载驱动程序(如果合并文件的顺序发生更改,并且另一个文件获胜,则同时执行此操作以防止出现问题)

    【讨论】:

    • 谢谢。 Class.forName("org.postgresql.Driver");实际上成功了。
    • @ChristianKammerer 是的,但正如我所提到的,我建议明确加载这两个驱动程序,以防将来的合并使用不同的顺序并且META-INF/services/java.sql.Driver 的 PostgreSQL 版本胜过 MySQL 版本。
    • 我不确定我是否完全理解,但这是加载驱动程序的竞争条件吗?我把它们都放进去了,;)
    • @ChristianKammerer 不,这是关于您创建一个包含多个 JAR 内容的单个 JAR,并且您合并这些 JAR 的方式不会合并存在于MySQL 连接器/J JAR 和 PostgreSQL JDBC JAR。相反,它只选择一个文件的内容(在这种情况下,来自 MySQL Connector/J 的那个)。因此,当DriverManager 发现可用的 JDBC 驱动程序时,它会找到一个服务定义文件,该文件仅列出 MySQL Connector/J 驱动程序。
    猜你喜欢
    • 1970-01-01
    • 2017-02-10
    • 1970-01-01
    • 2012-12-09
    • 2012-09-21
    • 2023-03-05
    • 2016-04-02
    相关资源
    最近更新 更多