groovy: Caught: java.sql.SQLException:没有找到合适的驱动程序,即使使用@GrabConfig(systemClassLoader=true)

2022-01-28 13:53:12 标签 javasql-serverjdbcgroovy

我有这个测试代码连接到一个SQL Server:

@GrabConfig(systemClassLoader=true)
@Grab(group='com.microsoft.sqlserver', module='mssql-jdbc', version='9.2.1.jre8')
import groovy.sql.Sql
def server = '10.6.6.1'
def port = '1433'
def user = 'sa'
def password = 'somepassword'
def url = "jdbc:sqlserver://${server}:${port};databaseName=master;"
Sql.withInstance(url, user, password) { sql ->
    def serverName = sql.firstRow('SELECT @@SERVERNAME')
    assert serverName[0]
}

如果我运行它,我得到:

Caught: java.sql.SQLException: No suitable driver found for jdbc:sqlserver://10.6.6.1:1433;databaseName=master;

java.sql.SQLException: No suitable driver found for jdbc:sqlserver://10.6.6.1:1433;databaseName=master;

test。run (test。groovy: 12)

驱动程序的jar肯定是由Grape下载的,因为在我的主目录的。groovy/目录的子目录中,我可以找到它。

但是没有办法我不能连接到服务器。

我现在用的是groovy 3。0。9,但我试过用更老的版本,结果还是一样。

编辑:

如果我在连接之前添加到代码:

Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver")

它是有效的,但很奇怪的是,我确信这是没有必要的。

如果有人能解释一下。

###仍然需要注册SQL驱动程序java.sql.DriverManager

每个jdbc驱动通常包含以下代码在XyzDriver类:

同样的microsoft sql驱动程序:https://github。com/microsoft/mssql-jdbc/blob/09d35bfc2338f1fc7c41a958d1e627fa0d6a2b65/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerDriver。java#L732

static {
    try {
        java.sql.DriverManager.registerDriver( new XyzDriver() )
    } catch (SQLException e) {
        ...
    }
}

这就是为什么你必须调用像Class。forName("XyzDriver")这样的代码来让驱动在DriverManager中自我注册

UPD: JDBC 4。0 / java8+

从javadoc: https://docs。oracle。com/javase/8/docs/api/java/sql/DriverManager。html

JDBC 4。0驱动程序必须包含META-INF/services/java。sql文件。司机……

当getConnection方法被调用时,DriverManager会尝试从初始化时加载的驱动和当前applet或应用中显式使用相同类加载器加载的驱动中找到合适的驱动。

Mssql-jdbc-9。2。1。jre8。jar兼容4。0版本。在META-INF/services/java。sql中包含com。microsoft。sqlserver。jdbc。SQLServerDriver。驱动程序文件

不过,让我们来检查一下DriverManager代码,看看它是如何查找驱动的:

http://hg。openjdk。java。net/jdk8/jdk8/jdk/file/tip/src/share/classes/java/sql/DriverManager。java#l100

DriverManager试图找到司机在它加载的时刻。因此JDBC驱动程序必须在应用程序启动时出现在类路径中才能自动注册。

static {
    loadInitialDrivers();
    println("JDBC DriverManager initialized");
}

但代码中的@Grab却不是这样。

作为grab之后的解决方案,你可以这样做来调用所有司机的自注册:

ServiceLoader.load(java.sql.Driver.class).iterator().findAll()
阅读全文

▼ 版权说明

相关文章也很精彩
推荐内容
更多标签
相关热门
全站排行
随便看看

错说 cuoshuo.com —— 程序员的报错记录

部分内容根据CC版权协议转载;网站内容仅供参考,生产环境使用务必查阅官方文档

辽ICP备19011660号-5

×

扫码关注公众号:职场神器
发送: 1
获取永久解锁本站全部文章的验证码