groovy:捕获:java.sql.SQLException:即使使用@GrabConfig(systemClassLoader=true)也找不到合适的驱动程序

资源 1

我有这个测试代码来连接到 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]

}

如果我运行它,我会得到:

捕获:java.sql.SQLException:找不到适合 jdbc:sqlserver://10.6.6.1:1433;databaseName=master; 的驱动程序 java.sql.SQLException: 找不到适合 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类中包含大约以下代码

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

微软 sql 驱动程序相同:https : //github.com/microsoft/mssql-jdbc/blob/09d35bfc2338f1fc7c41a958d1e627fa0d6a2b65/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerDriver.java#L732

这就是为什么你必须调用一个代码Class.forName("XyzDriver")来让驱动程序自注册DriverManager


更新: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.Driver...

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

mssql-jdbc-9.2.1.jre8.jar 与 4.0 兼容。它包含com.microsoft.sqlserver.jdbc.SQLServerDriverMETA-INF/services/java.sql.Driver文件中

但是,让我们检查 DriverManager 代码以及它如何查找驱动程序:

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

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

DriverManager尝试在加载时查找驱动程序。因此,jdbc 驱动程序必须在应用程序启动时出现在类路径中才能自动注册。

代码中的@Grab 并非如此。

作为抓取后的解决方法,您可以这样做来为所有驱动程序调用自注册:

ServiceLoader.load(java.sql.Driver.class).iterator().findAll()

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章