Apache Derby via Gradle:没有为jdbc:derby找到合适的驱动程序

问题描述 投票:0回答:1

我之前曾与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'
}

一个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 Client和我的Derby数据库版本是一样的。如果有帮助,我使用IntelliJ 2017.3和Java 8更新151在Mac OSX 10.12上。


编辑:为什么这个问题是不同的

我以前使用过Apache Derby,我可以在没有Gradle的情况下使用此代码。在另一个问题的答案中提到的这个例外的两个原因是:

  • 驱动程序未加载。 。 - 如果这是真的,那么为什么我没有在我尝试加载ClientDriver的顶部得到异常(或者我应该尝试加载其他类来排除这种可能性。)
  • JDBC URL格式错误。 - 我在非Gradle项目中对这个JDBC URL没有问题,所以我认为我的URL不对。如果这不正确,请纠正我。

编辑:解决方案(感谢Mark Rotteveel)

我显然没有意识到我使用的是嵌入式驱动程序,而不是客户端驱动程序。当我在没有Gradle的情况下使用它时,我曾经把所有的jar放在类路径中的整个Derby Lib目录中,而不用担心使用什么和什么不是。我的错。所以要改变的第一件事就是在我的try catch方法中删除main()

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'
}

这就是我所需要的。

java jdbc derby
1个回答
2
投票

您正在使用错误的Derby驱动程序,通过使用derbyclient,您指定要使用支持URL的Derby(网络)客户端驱动程序:

jdbc:derby://server[:port]/databaseName[;URLAttributes=value[;...]]

您的网址不匹配,因此被驱动程序拒绝,最终java.sql.DriverManager会报告它找不到合适的驱动程序。

相反,您需要使用依赖项org.apache.derby:derby,因为您似乎想要使用Derby Embedded驱动程序。此驱动程序包含在完整的derby程序包中,该程序包还包括Derby数据库本身,但不包括在derbyclient中。此驱动程序支持URL格式:

jdbc:derby:databaseName;URLAttributes

或者,您确实希望连接到外部运行的Derby服务器,在这种情况下,您使用的是错误的URL。

另见Libraries provided by DerbyDatabase connection URL

© www.soinside.com 2019 - 2024. All rights reserved.