我在运行时将 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/