通过 Gradle 的 Apache Derby:找不到适合 jdbc:derby 的驱动程序
Apache Derby via Gradle: No suitable driver found for jdbc:derby
我以前使用过 Apache Derby,但我从未在 Gradle 项目中使用过它。我使用 ij
Derby 工具通过 运行 以下命令在项目的根目录中创建了一个简单的 Derby 数据库:
connect 'jdbc:derby:MyDbTest;create=true';
CREATE TABLE Hashes (
string_id int,
RandString varchar(255)
);
INSERT INTO Hashes (string_id, RandString) values (1, 'sdfdsfsw');
SELECT * FROM Hashes;
在此之后,我在 Main.java
中的 Java 代码如下所示:
package com.company;
import java.io.File;
import java.sql.*;
public class Main {
public static void main(String[] args) {
System.out.println("Current working directory : "+ new File(".").getAbsolutePath());
try {
Class.forName("org.apache.derby.jdbc.ClientDriver").newInstance();
} catch (Exception e) {
e.printStackTrace(); //Does not get executed!
}
Connection conn = null;
try
{
conn = DriverManager.getConnection("jdbc:derby:MyDbTest"); //Exception here!!
System.out.println("Connected to database MyDbTest");
Statement s = conn.createStatement();
ResultSet rs = s.executeQuery(
"select string_id, RandString from Hashes");
while(rs.next()) {
int string_id = rs.getInt("string_id");
String randString = rs.getString("RandString");
System.out.printf("string_id: %s, RandString: %s\n", string_id, randString);
}
}
catch (SQLException sqle)
{
printSQLException(sqle);
} finally {
try {
if (conn != null) {
conn.close();
DriverManager.getConnection("jdbc:derby:;shutdown=true;deregister=false");
}
} catch (SQLException sqle) {
printSQLException(sqle);
}
}
}
public static void printSQLException(SQLException e)
{
//According to this page:
//https://db.apache.org/derby/papers/DerbyTut/embedded_intro.html
//" A clean shutdown always throws SQL exception XJ015, which can be ignored."
if(e.getSQLState().equals("XJ015")) return; //Ignore
// Unwraps the entire exception chain to unveil the real cause of the
// Exception.
while (e != null)
{
System.err.println("\n----- SQLException -----");
System.err.println(" SQL State: " + e.getSQLState());
System.err.println(" Error Code: " + e.getErrorCode());
System.err.println(" Message: " + e.getMessage());
// for stack traces, refer to derby.log or uncomment this:
e.printStackTrace(System.err);
e = e.getNextException();
}
}
}
我最初似乎能够加载 ClientDriver
,但是当我尝试连接到数据库时,我得到了 Exception
。第一行确保当前工作目录是 MyDbTest
数据库所在项目的根目录。
我的 build.gradle
文件如下所示:
apply plugin: 'java'
apply plugin:'application'
mainClassName = "com.company.Main"
repositories {
mavenLocal()
mavenCentral()
}
dependencies {
compile group: 'org.apache.derby', name: 'derbyclient', version: '10.14.1.0'
compile group: 'org.apache.derby', name: 'derbytools', version: '10.14.1.0'
runtime group: 'org.apache.derby', name: 'derbyclient', version: '10.14.1.0'
runtime group: 'org.apache.derby', name: 'derbytools', version: '10.14.1.0'
}
A gradle run
给我:
Current working directory : /Users/<myname>/Documents/sources/tempFive/.
----- SQLException -----
SQL State: 08001
Error Code: 0
Message: No suitable driver found for jdbc:derby:MyDbTest
java.sql.SQLException: No suitable driver found for jdbc:derby:MyDbTest
at java.sql.DriverManager.getConnection(DriverManager.java:689)
at java.sql.DriverManager.getConnection(DriverManager.java:270)
at com.company.Main.main(Main.java:25)
我已确保我的 Derby 客户端和我的 Derby 数据库版本相同。我正在 Mac OSX 10.12 使用 IntelliJ 2017.3 和 Java 8 update 151 如果有帮助的话。
编辑:为什么这个问题不同
我以前使用过 Apache Derby,我可以在没有 Gradle 的情况下使用此代码。另一个问题的回答中提到的导致这个异常的两个原因是:
- 未加载驱动程序。。 - 如果这是真的,那么为什么我在尝试加载
ClientDriver
的顶部没有出现异常(或者我应该尝试加载其他一些 class 来排除这个可能性。)
- JDBC URL 格式不正确。 - 我对这个 JDBC URL 没有问题一个非 Gradle 项目,所以我认为我的 URL 没有错。 如有不妥请指正。
编辑:解决方案(感谢 Mark Rotteveel)
我显然没有意识到我使用的是嵌入式驱动程序而不是客户端驱动程序。当我在没有 Gradle 的情况下使用它时,我习惯于将所有 jar 放在 class 路径中的整个 Derby Lib 目录中,而不用担心使用了什么和没有使用什么。我的错。因此,首先要更改的是删除我的 main()
方法中的 try catch
:
try {
Class.forName("org.apache.derby.jdbc.ClientDriver").newInstance();
} catch (Exception e) {
e.printStackTrace(); //Does not get executed!
}
从未使用过ClientDriver
,因此加载它没有意义。接下来,正如 Mark Rotteveel 指出的那样,我只需要依赖 org.apache.derby:derby
。这是我真正的错误,所以我把完整更正的 build.gradle
文件放在下面:
apply plugin: 'java'
apply plugin:'application'
mainClassName = "com.company.Main"
repositories {
mavenLocal()
mavenCentral()
}
dependencies {
compile group: 'org.apache.derby', name: 'derby', version: '10.14.1.0'
}
这就是我所需要的。
您使用了错误的 Derby 驱动程序,通过使用 derbyclient
,您指定要使用支持 URL:
的 Derby(网络)客户端驱动程序
jdbc:derby://server[:port]/databaseName[;URLAttributes=value[;...]]
你的URL不匹配,所以被驱动拒绝了,最终java.sql.DriverManager
会报找不到合适的驱动
相反,您需要使用依赖项 org.apache.derby:derby
,因为您似乎想要使用 Derby Embedded 驱动程序。此驱动程序包含在完整的 derby
包中,该包还包含 Derby 数据库本身,但不包含在 derbyclient
中。此驱动程序支持 URL 格式:
jdbc:derby:databaseName;URLAttributes
或者您确实想连接到外部 运行 Derby 服务器,在这种情况下,您使用的是错误的 URL。
我以前使用过 Apache Derby,但我从未在 Gradle 项目中使用过它。我使用 ij
Derby 工具通过 运行 以下命令在项目的根目录中创建了一个简单的 Derby 数据库:
connect 'jdbc:derby:MyDbTest;create=true';
CREATE TABLE Hashes (
string_id int,
RandString varchar(255)
);
INSERT INTO Hashes (string_id, RandString) values (1, 'sdfdsfsw');
SELECT * FROM Hashes;
在此之后,我在 Main.java
中的 Java 代码如下所示:
package com.company;
import java.io.File;
import java.sql.*;
public class Main {
public static void main(String[] args) {
System.out.println("Current working directory : "+ new File(".").getAbsolutePath());
try {
Class.forName("org.apache.derby.jdbc.ClientDriver").newInstance();
} catch (Exception e) {
e.printStackTrace(); //Does not get executed!
}
Connection conn = null;
try
{
conn = DriverManager.getConnection("jdbc:derby:MyDbTest"); //Exception here!!
System.out.println("Connected to database MyDbTest");
Statement s = conn.createStatement();
ResultSet rs = s.executeQuery(
"select string_id, RandString from Hashes");
while(rs.next()) {
int string_id = rs.getInt("string_id");
String randString = rs.getString("RandString");
System.out.printf("string_id: %s, RandString: %s\n", string_id, randString);
}
}
catch (SQLException sqle)
{
printSQLException(sqle);
} finally {
try {
if (conn != null) {
conn.close();
DriverManager.getConnection("jdbc:derby:;shutdown=true;deregister=false");
}
} catch (SQLException sqle) {
printSQLException(sqle);
}
}
}
public static void printSQLException(SQLException e)
{
//According to this page:
//https://db.apache.org/derby/papers/DerbyTut/embedded_intro.html
//" A clean shutdown always throws SQL exception XJ015, which can be ignored."
if(e.getSQLState().equals("XJ015")) return; //Ignore
// Unwraps the entire exception chain to unveil the real cause of the
// Exception.
while (e != null)
{
System.err.println("\n----- SQLException -----");
System.err.println(" SQL State: " + e.getSQLState());
System.err.println(" Error Code: " + e.getErrorCode());
System.err.println(" Message: " + e.getMessage());
// for stack traces, refer to derby.log or uncomment this:
e.printStackTrace(System.err);
e = e.getNextException();
}
}
}
我最初似乎能够加载 ClientDriver
,但是当我尝试连接到数据库时,我得到了 Exception
。第一行确保当前工作目录是 MyDbTest
数据库所在项目的根目录。
我的 build.gradle
文件如下所示:
apply plugin: 'java'
apply plugin:'application'
mainClassName = "com.company.Main"
repositories {
mavenLocal()
mavenCentral()
}
dependencies {
compile group: 'org.apache.derby', name: 'derbyclient', version: '10.14.1.0'
compile group: 'org.apache.derby', name: 'derbytools', version: '10.14.1.0'
runtime group: 'org.apache.derby', name: 'derbyclient', version: '10.14.1.0'
runtime group: 'org.apache.derby', name: 'derbytools', version: '10.14.1.0'
}
A gradle run
给我:
Current working directory : /Users/<myname>/Documents/sources/tempFive/.
----- SQLException -----
SQL State: 08001
Error Code: 0
Message: No suitable driver found for jdbc:derby:MyDbTest
java.sql.SQLException: No suitable driver found for jdbc:derby:MyDbTest
at java.sql.DriverManager.getConnection(DriverManager.java:689)
at java.sql.DriverManager.getConnection(DriverManager.java:270)
at com.company.Main.main(Main.java:25)
我已确保我的 Derby 客户端和我的 Derby 数据库版本相同。我正在 Mac OSX 10.12 使用 IntelliJ 2017.3 和 Java 8 update 151 如果有帮助的话。
编辑:为什么这个问题不同
我以前使用过 Apache Derby,我可以在没有 Gradle 的情况下使用此代码。另一个问题的回答中提到的导致这个异常的两个原因是:
- 未加载驱动程序。。 - 如果这是真的,那么为什么我在尝试加载
ClientDriver
的顶部没有出现异常(或者我应该尝试加载其他一些 class 来排除这个可能性。) - JDBC URL 格式不正确。 - 我对这个 JDBC URL 没有问题一个非 Gradle 项目,所以我认为我的 URL 没有错。 如有不妥请指正。
编辑:解决方案(感谢 Mark Rotteveel)
我显然没有意识到我使用的是嵌入式驱动程序而不是客户端驱动程序。当我在没有 Gradle 的情况下使用它时,我习惯于将所有 jar 放在 class 路径中的整个 Derby Lib 目录中,而不用担心使用了什么和没有使用什么。我的错。因此,首先要更改的是删除我的 main()
方法中的 try catch
:
try {
Class.forName("org.apache.derby.jdbc.ClientDriver").newInstance();
} catch (Exception e) {
e.printStackTrace(); //Does not get executed!
}
从未使用过ClientDriver
,因此加载它没有意义。接下来,正如 Mark Rotteveel 指出的那样,我只需要依赖 org.apache.derby:derby
。这是我真正的错误,所以我把完整更正的 build.gradle
文件放在下面:
apply plugin: 'java'
apply plugin:'application'
mainClassName = "com.company.Main"
repositories {
mavenLocal()
mavenCentral()
}
dependencies {
compile group: 'org.apache.derby', name: 'derby', version: '10.14.1.0'
}
这就是我所需要的。
您使用了错误的 Derby 驱动程序,通过使用 derbyclient
,您指定要使用支持 URL:
jdbc:derby://server[:port]/databaseName[;URLAttributes=value[;...]]
你的URL不匹配,所以被驱动拒绝了,最终java.sql.DriverManager
会报找不到合适的驱动
相反,您需要使用依赖项 org.apache.derby:derby
,因为您似乎想要使用 Derby Embedded 驱动程序。此驱动程序包含在完整的 derby
包中,该包还包含 Derby 数据库本身,但不包含在 derbyclient
中。此驱动程序支持 URL 格式:
jdbc:derby:databaseName;URLAttributes
或者您确实想连接到外部 运行 Derby 服务器,在这种情况下,您使用的是错误的 URL。