java - 在运行时添加 JDBC jar 时,没有找到适合 HSQL 数据库的 JDBC 驱动程序?

标签 java maven jdbc jar hsqldb

我在运行时将 JDBC jar 用于 HSQL 数据库(即:它从设置文件加载此 jar 文件的文件路径,而不是作为 Maven 依赖项进行硬修复)。但是,我无法像以前一样通过在运行时添加 JDBC jar 来获得与此 HSQL 数据库的 SQL 连接。以下是我用来在运行时加载 HSQL DB 的 JDBC jar 文件的代码:

Connection connection;
try {
    // this is hard fix for example, ~/hsqldb-2.3.3.jar should be gotten from a setting file
    File jdbcJarFile = new File("~/hsqldb-2.3.3.jar");          
    URL urls[] = { jdbcJarFile.toURI().toURL() };
    URLClassLoader loader = new URLClassLoader(urls, DatabaseUtil.class.getClassLoader());
    Thread.currentThread().setContextClassLoader(loader);
    loader.loadClass("org.hsqldb.jdbcDriver");

    // no error but nothing happens
    Class.forName("org.hsqldb.jdbcDriver", true, loader); 

    // throw exception because cannot find the driver for HSQL DB
    // with this url: jdbc:hsqldb:file://home/abc/hsqldb/test        
    connection = DriverManager.getConnection(datasourceURL, datasourceUserName, datasourcePassword);
} catch(Exception ex) {
    //  (java.sql.SQLException) java.sql.SQLException: No suitable driver found for jdbc:hsqldb:file://home/abc/hsqldb/test
    throw new SQLException(ex);
}

我不想在编译时将此 jar 添加到类路径,只想在运行时添加。

最佳答案

问题是 DriverManager 不允许您的类看到此驱动程序,因为您的类不是由包含 HSQLDB 驱动程序的类加载器层次结构加载的。

具体来说,DriverManager.getConnection 迭代所有驱动程序,并调用方法 isDriverAllowed,该方法最终检查驱动程序是否可以从调用者类的类加载器加载,通过使用驱动程序名称调用Class.forName,并检查它是否返回与当前驱动程序相同的类。这会失败,因为驱动程序类不在调用者类或其任何父类的类加载器中。

要使其正常工作,您需要使用与驱动程序相同的类加载器(或该类加载器的子加载器)来加载调用者类,或者您需要通过加载驱动程序来破解类加载器层次结构在系统类加载器中(在 Java 9 中这变得相当困难,即使不是不可能)。

这样做可能会更简单:

Driver driver = (Driver) Class.forName("org.hsqldb.jdbc.JDBCDriver", true, loader).newInstance();
Properties props = new Properties();
props.setProperty("user", datasourceUserName);
props.setProperty("password", datasourcePassword);
connection = driver.connect(datasourceURL, props);

这意味着您完全跳过DriverManager。我不确定这是否会因为类加载器问题而困扰您,所以我建议您仔细测试一下。

关于java - 在运行时添加 JDBC jar 时,没有找到适合 HSQL 数据库的 JDBC 驱动程序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48099330/

相关文章:

java - jprogressbar 无法正常工作(可能是由于线程)

java - Android NDK ndk-build helloJni错误

java - Spring Boot 应用程序不使用 java -jar 运行

java - 创建 Google Java Checkstyle XML 文件的自定义版本

scala - 从Spark作业中调用JDBC进行Impala/Hive并创建表

java - 不同类之间共享对象

java - 如何向该驱动程序添加一个构造函数,以便它同时适用于数组列表和链表?

Java使用Annotation创建类的实例

maven - 如何 OSGIfy 一个库

java - ORA-01017: 用户名/密码无效;使用 wss4j 时登录被拒绝