我在运行时使用JDBC jar for HSQL db (即:它从设置文件加载到这个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添加到类路径中,只想在运行时添加。
发布于 2018-01-05 18:02:18
问题是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。我不确定这是否会因为类加载器问题而影响您,所以我建议您仔细测试一下。
发布于 2018-01-05 18:23:15
所以我找不到一种方法在运行时通过DriverManager获取JDBC连接,但是我可以使用DataSource来实现
// Load JDBC jar from setting file normally
File jdbcJarFile = new File(pathToJarFile);
URL urls[] = jdbcJarFile.toURI().toURL();
URLClassLoader loader = new URLClassLoader(urls, Thread.currentThread().getContextClassLoader());
Thread.currentThread().setContextClassLoader(loader);
// Create a javax.sql DataSource object (org.springframework.boot.autoconfigure.jdbc.DataSourceBuilder)
DataSource dataSource = DataSourceBuilder.create().url("hsqlb_url").username("sa").password("").build();
// Get a java.sql.Connection object
Connection connection = dataSource.getConnection(); https://stackoverflow.com/questions/48099330
复制相似问题