为什么 DriverManager.getConnection() 查找在 GroovyConsole 中失败?

Why does DriverManager.getConnection() lookup fail in GroovyConsole?

以下 Groovy 脚本在命令行中可以正常工作。 (我成功获得连接。)

// ---- jdbc_test.groovy
import java.sql.*
Class.forName("com.mysql.jdbc.Driver")
def con = DriverManager.getConnection(
    "jdbc:mysql://localhost:3306/test",
    "root",
    "password")
println con

> groovy -cp lib\mysql-connector-java-5.1.25-bin.jar script\jdbc_test.groovy
com.mysql.jdbc.JDBC4Connection@6025e1b6

但是如果将相同的脚本加载到 GroovyConsole (2.4.3) 和 运行 - 在使用 'Script' 添加 mysql-connector-java-5.1.25-bin.jar 之后 | 'Add Jar(s) to ClassPath' - 失败:

java.sql.SQLException: No suitable driver found for jdbc:mysql://localhost:3306/test
at java_sql_DriverManager$getConnection.call(Unknown Source)
at jdbc_test.run(jdbc_test.groovy:3)

我已添加到 Groovy 控制台中的 class 路径并进行试验的所有其他包或 class 都有效。 Groovy 的 class 加载和 DriverManager 的工作方式是否有一些意外的交互?

有办法解决这个问题吗?我正在尝试使用 Groovy 控制台以交互方式测试一些 JDBC 代码(函数库,每个函数都将 Connection 作为其第一个参数)。

更新:Class.forName() 部分似乎工作正常。如果我 'Script' | 'Clear Script Context' 并重新 运行 Groovy 控制台中的脚本,我反而得到:

java.lang.ClassNotFoundException: com.mysql.jdbc.Driver

如果我重新添加 mysql-connector-java-5.1.25-bin.jar,我会返回:

java.sql.SQLException: No suitable driver found for jdbc:mysql://localhost:3306/test

解决方法:驱动程序必须在class路径上。

原因: 如果您查看 DriverManager class,您会发现这样的代码:Class.forName(driver.getClass().getName(), true, classLoader);。这是为了检查驱动程序是否可以从您的 classloader 上下文访问。该上下文是通过返回调用 DriverManager 的 class 来确定的。此代码是为 Java 编写的,因此假定调用堆栈上有一定数量的帧要返回。由于 Groovy 不直接调用(除非你使用 @CompileStatic),这个数字是错误的并且通常导致 Groovy 核心 class 被选择,导致 Groovy main要选择的加载程序....在过去,由于反射,这通常甚至是 JDK 系统 class 加载程序。因此,即使驱动程序已加载并注册,您也无法访问它。

注意: 使用 jdbc4 驱动程序应该自行注册,只需位于 classpath