Java.sql.SQLException khét tiếng: Không tìm thấy trình điều khiển phù hợp


89

Tôi đang cố gắng thêm JSP hỗ trợ cơ sở dữ liệu vào ứng dụng Tomcat 5.5 hiện có (GeoServer 2.0.0, nếu điều đó có ích).

Bản thân ứng dụng nói chuyện với Postgres rất tốt, vì vậy tôi biết rằng cơ sở dữ liệu đã được thiết lập, người dùng có thể truy cập nó, tất cả những thứ tốt đó. Những gì tôi đang cố gắng thực hiện là một truy vấn cơ sở dữ liệu trong JSP mà tôi đã thêm. Tôi đã sử dụng ví dụ cấu hình trong ví dụ nguồn dữ liệu Tomcat khá nhiều. Các taglib cần thiết ở đúng vị trí - không có lỗi nào xảy ra nếu tôi chỉ có các tham chiếu taglib, vì vậy nó đang tìm các JAR đó. Trình điều khiển postgres jdbc, postgresql-8.4.701.jdbc3.jar nằm trong $ CATALINA_HOME / common / lib.

Đây là đầu của JSP:

<%@ taglib uri="http://java.sun.com/jsp/jstl/sql" prefix="sql" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>

<sql:query var="rs" dataSource="jdbc/mmas">
  select current_validstart as ValidTime from runoff_forecast_valid_time
</sql:query>

Phần có liên quan từ $ CATALINA_HOME / conf / server.xml, bên <Host>trong lần lượt nằm trong <Engine>:

<Context path="/gs2" allowLinking="true">
  <Resource name="jdbc/mmas" type="javax.sql.Datasource"
      auth="Container" driverClassName="org.postgresql.Driver"
      maxActive="100" maxIdle="30" maxWait="10000"
      username="mmas" password="very_secure_yess_precious!"
      url="jdbc:postgresql//localhost:5432/mmas" />
</Context>

Những dòng này là dòng cuối cùng trong thẻ trong webapps / gs2 / WEB-INF / web.xml:

<resource-ref>
  <description>
     The database resource for the MMAS PostGIS database
  </description>
  <res-ref-name>
     jdbc/mmas
  </res-ref-name>
  <res-type>
     javax.sql.DataSource
  </res-type>
  <res-auth>
     Container
  </res-auth>
</resource-ref>

Cuối cùng, ngoại lệ:

   exception
    org.apache.jasper.JasperException: Unable to get connection, DataSource invalid: "java.sql.SQLException: No suitable driver"
    [...wads of ensuing goo elided]

Xem câu trả lời của tôi: stackoverflow.com/a/38656446/632951
Pacerier

Câu trả lời:


106

Java.sql.SQLException khét tiếng: Không tìm thấy trình điều khiển phù hợp

Ngoại lệ này về cơ bản có thể có hai nguyên nhân:

1. Trình điều khiển JDBC không được tải

Bạn cần đảm bảo rằng trình điều khiển JDBC được đặt trong /libthư mục riêng của máy chủ .

Hoặc, khi bạn thực sự không sử dụng nguồn dữ liệu nhóm kết nối do máy chủ quản lý, nhưng đang tìm kiếm thủ công DriverManager#getConnection()trong WAR, thì bạn cần đặt trình điều khiển JDBC trong WAR /WEB-INF/libvà thực hiện ..

Class.forName("com.example.jdbc.Driver");

.. trong mã của bạn trướcDriverManager#getConnection() cuộc gọi đầu tiên, nhờ đó bạn đảm bảo rằng bạn không nuốt / bỏ qua bất kỳ ClassNotFoundExceptionthứ gì có thể bị nó ném ra và tiếp tục dòng mã như thể không có gì đặc biệt xảy ra. Xem thêm Tôi phải đặt trình điều khiển JDBC cho nhóm kết nối của Tomcat ở đâu?

2. Hoặc, URL JDBC sai cú pháp

Bạn cần đảm bảo rằng URL JDBC tuân theo tài liệu trình điều khiển JDBC và lưu ý rằng nó thường phân biệt chữ hoa chữ thường. Khi URL JDBC không trả về truecho Driver#acceptsURL()bất kỳ trình điều khiển đã tải nào, thì bạn cũng sẽ nhận được chính xác ngoại lệ này.

Trong trường hợp của PostgreSQL, nó được ghi lại ở đây .

Với JDBC, cơ sở dữ liệu được đại diện bởi một URL (Bộ định vị tài nguyên đồng nhất). Với PostgreSQL ™, điều này có một trong các dạng sau:

  • jdbc:postgresql:database
  • jdbc:postgresql://host/database
  • jdbc:postgresql://host:port/database

Trong trường hợp của MySQL, nó được ghi lại ở đây .

Định dạng chung cho URL JDBC để kết nối với máy chủ MySQL như sau, với các mục trong dấu ngoặc vuông ( [ ]) là tùy chọn:

jdbc:mysql://[host1][:port1][,[host2][:port2]]...[/[database]] » [?propertyName1=propertyValue1[&propertyName2=propertyValue2]...]

Trong trường hợp của Oracle, nó được ghi lại ở đây .

Có 2 cú pháp URL, cú pháp cũ sẽ chỉ hoạt động với SID và cú pháp mới với tên dịch vụ Oracle.

Cú pháp cũ jdbc:oracle:thin:@[HOST][:PORT]:SID

Cú pháp mới jdbc:oracle:thin:@//[HOST][:PORT]/SERVICE


Xem thêm:


Cảm ơn các bạn! Xin lỗi lần thử đầu tiên không có trong OP, chỉ là jdbc: postgresql: mmas (và tôi đã thử người khác!). Đáng buồn thay, với URL của araqnid, kết quả tương tự. Đêm qua tôi đã hoán đổi nội dung tablib cho Java nhúng (ick) và nó hoạt động tốt: hãy thử {Class.forName ("org.postgresql.Driver"). NewInstance (); con = DriverManager.getConnection ("jdbc: postgresql: mmas", "mmas", "passwd"); stmt = con.createStatement (); rs = stmt.executeQuery ("chọn yada yada"); if (rs! = null && rs.next ()) {// gặt hái danh tiếng, tài sản, vinh quang, ví dụ babes Jakarta là w / taglibs, vì vậy tôi bắt đầu theo cách đó.
Rick Wayne

Ah. Nhận xét không quá nhiều về định dạng mã. E hèm. Người mới của tôi đang hiển thị? (ZIIP!) Dù sao, ví dụ Jakarta là tất cả về việc sử dụng cú pháp <sql: query> thay vì chỉ nhúng mã Java và tôi đồng ý rằng đó là một cách dễ dàng hơn nhiều để làm điều đó. Người ta không cần phải gọi forName () và getConnection () một cách rõ ràng, phải không? Nhưng phương pháp hack-the-driver-code-in-the-Presentation-layer cũ xấu xí vẫn hoạt động tốt, trước tiên hãy thử. Vì vậy, tôi cảm thấy bối rối, nhưng bây giờ vấn đề về bảo trì / thẩm mỹ nhiều hơn là "Cái này bị hỏng, hãy sửa nó hoặc học lại kỹ năng lật bánh mì kẹp thịt của bạn."
Rick Wayne

IMHO sử dụng taglib sql chỉ tốt hơn một chút so với thực hiện JDBC trong scriptlets ... thích một mẫu điều khiển / chế độ xem trong đó nội dung db được thực hiện trước và JSP chỉ hiển thị nội dung. Mặc dù vậy, mỗi người đều riêng và sử dụng sql: query giúp mọi thứ trở nên đơn giản :) (ish)
araqnid

Tôi chưa bao giờ nói rằng tôi đồng ý với việc sử dụng JSTL SQL taglib, nhưng đó không phải là chủ đề của chủ đề này.
BalusC

2
Cảm ơn, các định dạng chuỗi kết nối JDBC của bạn rất hữu ích!
Jay Taylor

15
url="jdbc:postgresql//localhost:5432/mmas"

URL đó có vẻ sai, bạn có cần những thứ sau không?

url="jdbc:postgresql://localhost:5432/mmas"

15

Tôi đã quên thêm Trình điều khiển JDBC PostgreSQL vào dự án của mình ( Mvnrepository ).

Gradle :

// http://mvnrepository.com/artifact/postgresql/postgresql
compile group: 'postgresql', name: 'postgresql', version: '9.0-801.jdbc4'

Maven :

<dependency>
    <groupId>postgresql</groupId>
    <artifactId>postgresql</artifactId>
    <version>9.0-801.jdbc4</version>
</dependency>

Bạn cũng có thể tải về các JAR và nhập khẩu để dự án của bạn bằng tay.


12

Tôi đã đối mặt với vấn đề tương tự. Dự án của tôi trong ngữ cảnh là Dự án web động (Java 8 + Tomcat 8) và lỗi dành cho ngoại lệ Trình điều khiển PostgreSQL: Không tìm thấy trình điều khiển phù hợp

Nó đã được giải quyết bằng cách thêm Class.forName("org.postgresql.Driver")trước khi gọi getConnection()phương thức

Đây là Mã mẫu của tôi:

try {
            Connection conn = null;
            Class.forName("org.postgresql.Driver");
            conn = DriverManager.getConnection("jdbc:postgresql://" + host + ":" + port + "/?preferQueryMode="
                    + sql_auth,sql_user , sql_password);
        } catch (Exception e) {
            System.out.println("Failed to create JDBC db connection " + e.toString() + e.getMessage());
        }

3

Tôi thấy mẹo theo dõi hữu ích để loại bỏ vấn đề này trong Tomcat -

đảm bảo tải trình điều khiển trước khi thực hiện Class.forName ("org.postgresql.Driver"); trong mã của bạn.

Đây là từ bài đăng - https://www.postgresql.org/message-id/e13c14ec050510103846db6b0e@mail.gmail.com

Mã jdbc hoạt động tốt như một chương trình độc lập nhưng trong TOMCAT, nó đã đưa ra lỗi -'Không tìm thấy trình điều khiển phù hợp '


Vui lòng không liên kết chỉ có câu trả lời - mô tả ngắn gọn những gì đằng sau đó!
monamona

Liên kết đến một giải pháp được hoan nghênh, nhưng hãy đảm bảo rằng câu trả lời của bạn hữu ích nếu không có nó: thêm ngữ cảnh xung quanh liên kết để những người dùng đồng nghiệp của bạn sẽ biết nó là gì và tại sao nó ở đó, sau đó trích dẫn phần có liên quan nhất của trang bạn ' đang liên kết lại trong trường hợp trang đích không có sẵn. Các câu trả lời ít hơn một liên kết có thể bị xóa .
Peter

1

Có thể cần lưu ý rằng điều này cũng có thể xảy ra khi Windows chặn các bản tải xuống mà nó cho là không an toàn. Điều này có thể được giải quyết bằng cách nhấp chuột phải vào tệp jar (chẳng hạn như ojdbc7.jar) và chọn hộp 'Bỏ chặn' ở dưới cùng.

Hộp thoại Thuộc tính Tệp Windows JAR :
Hộp thoại Thuộc tính Tệp Windows JAR


1

Cũng như việc thêm trình kết nối MySQL JDBC đảm bảo context.xml (nếu không được giải nén trong thư mục Tomcat webapps) với các định nghĩa kết nối DB của bạn được bao gồm trong thư mục Tomcats conf.


1

Một sai lầm rất ngớ ngẩn có thể xảy ra là thêm khoảng trống ở đầu kết nối URL JDBC.

Ý của tôi là:-

giả sử bạn có bymistake đưa ra url jdbc như

String jdbcUrl=" jdbc:mysql://localhost:3306/web_customer_tracker?useSSL=false&serverTimeZone=UTC";

(Chú ý rằng có một khoảng trống trong phần nhìn chằm chằm của url, điều này sẽ gây ra lỗi)

cách đúng phải là:

String jdbcUrl="jdbc:mysql://localhost:3306/web_customer_tracker?useSSL=false&serverTimeZone=UTC";

(Chú ý không có khoảng trắng trong phần nhìn chằm chằm, bạn có thể cho khoảng trắng ở cuối url nhưng an toàn là không)


0

Tôi đang sử dụng jruby, trong trường hợp của tôi, tôi đã tạo trong config / khởi tạo

postgres_driver.rb

$CLASSPATH << '~/.rbenv/versions/jruby-1.7.17/lib/ruby/gems/shared/gems/jdbc-postgres-9.4.1200/lib/postgresql-9.4-1200.jdbc4.jar'

hoặc bất cứ nơi nào trình điều khiển của bạn, và đó là nó!


0

Tôi đã gặp sự cố chính xác này khi phát triển ứng dụng Spring Boot trong STS, nhưng cuối cùng vẫn triển khai cuộc chiến đóng gói cho WebSphere (v.9). Dựa trên những câu trả lời trước đây, tình huống của tôi là duy nhất. ojdbc8.jar đã ở trong thư mục WEB-INF / lib của tôi với bộ tải lớp Parent Last, nhưng nó luôn thông báo rằng không tìm thấy trình điều khiển phù hợp.

Vấn đề cuối cùng của tôi là tôi đã sử dụng lớp DataSource không chính xác vì tôi chỉ theo dõi các hướng dẫn / ví dụ trực tuyến. Tìm thấy gợi ý nhờ David Dai bình luận cho câu hỏi của riêng anh ấy ở đây: Spring JDBC Không thể tải lớp trình điều khiển JDBC [oracle.jdbc.driver.OracleDriver]

Sau đó cũng tìm thấy ví dụ về Spring guru với trình điều khiển cụ thể của Oracle: https://springframework.guru/configuring-spring-boot-for-oracle/

Ví dụ ném lỗi bằng cách sử dụng org.springframework.jdbc.datasource.DriverManagerDataSourcedựa trên các ví dụ chung.

@Config
@EnableTransactionManagement
public class appDataConfig {
 \* Other Bean Defs *\
    @Bean
    public DataSource dataSource() {
        // configure and return the necessary JDBC DataSource
        DriverManagerDataSource dataSource = new DriverManagerDataSource("jdbc:oracle:thin:@//HOST:PORT/SID", "user", "password");
        dataSource.setSchema("MY_SCHEMA");
        return dataSource;
    }
}

Và exapmle đã sửa bằng cách sử dụng oracle.jdbc.pool.OracleDataSource:

@Config
@EnableTransactionManagement
public class appDataConfig {
/* Other Bean Defs */
@Bean
    public DataSource dataSource() {
        // configure and return the necessary JDBC DataSource
        OracleDataSource datasource = null;
        try {
            datasource = new OracleDataSource();
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        datasource.setURL("jdbc:oracle:thin:@//HOST:PORT/SID");
        datasource.setUser("user");
        datasource.setPassword("password");

        return datasource;
    }
}

0

Tôi đã gặp vấn đề tương tự với nguồn dữ liệu mysql sử dụng dữ liệu mùa xuân sẽ hoạt động bên ngoài nhưng đã cho tôi lỗi này khi triển khai trên tomcat.

Lỗi đã biến mất khi tôi thêm trình điều khiển jar mysql-connector-java-8.0.16.jar vào thư mục jres lib / ext

Tuy nhiên, tôi không muốn làm điều này trong quá trình sản xuất vì sợ ảnh hưởng đến các ứng dụng khác. Việc xác định rõ ràng lớp trình điều khiển đã giải quyết được vấn đề này cho tôi

    spring.datasource.driver-class-name: com.mysql.cj.jdbc.Driver

0

Chạy javavới CLASSPATHbiến môi trường trỏ đến tệp JAR của trình điều khiển, ví dụ:

CLASSPATH='.:drivers/mssql-jdbc-6.2.1.jre8.jar' java ConnectURL

Trong trường hợp drivers/mssql-jdbc-6.2.1.jre8.jarlà con đường dẫn đến tập tin trình điều khiển (ví dụ như JDBC cho cho SQL Server ).

Đây ConnectURLlà ứng dụng mẫu từ trình điều khiển đó ( samples/connections/ConnectURL.java), được biên dịch qua javac ConnectURL.java.


0

Trong trường hợp của tôi, tôi đang làm việc trên một dự án Java với Maven và gặp phải lỗi này. Trong tệp pom.xml của bạn, hãy đảm bảo rằng bạn có phần phụ thuộc này

<dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>8.0.11</version>
    </dependency>
  </dependencies>

và nơi bạn tạo kết nối có một cái gì đó như thế này

public Connection createConnection() {
        try {
            String url = "jdbc:mysql://localhost:3306/yourDatabaseName";
            String username = "root"; //your my sql username here
            String password = "1234"; //your mysql password here

            Class.forName("com.mysql.cj.jdbc.Driver");
            return DriverManager.getConnection(url, username, password);
        } catch (SQLException | ClassNotFoundException e) {
            e.printStackTrace();
        }

        return null;
    }

Bạn không cần phải gọi Class.forName. DriverManagernên có thể tìm thấy nó.
Stephen C

Bạn có thể đúng. Java không phải là ngôn ngữ viết mã chính của tôi.
Justice Bringer

0

Bạn sẽ gặp lỗi tương tự nếu không có định nghĩa Tài nguyên được cung cấp ở đâu đó cho ứng dụng của bạn - rất có thể là trong tệp ngữ cảnh trung tâm.xml hoặc tệp ngữ cảnh riêng lẻ trong conf / Catalina / localhost. Và nếu sử dụng các tệp ngữ cảnh riêng lẻ, hãy cẩn thận rằng Tomcat tự do xóa chúng bất cứ lúc nào bạn xóa / hủy triển khai tệp .war tương ứng.


0

Bất kể chủ đề này trở nên cũ đến mức nào, mọi người sẽ tiếp tục đối mặt với vấn đề này.

Trường hợp của tôi: Tôi có thiết lập OpenJDK và maven mới nhất (tại thời điểm đăng bài). Tôi đã thử tất cả các phương pháp được đưa ra ở trên, với maven / out và thậm chí các giải pháp trên các bài đăng của chị em trên StackOverflow. Tôi không sử dụng bất kỳ IDE nào hoặc bất kỳ thứ gì khác, chạy từ CLI trần để chỉ chứng minh logic cốt lõi.

Đây là những gì cuối cùng đã hoạt động.

  • Tải xuống trình điều khiển từ trang web chính thức. (đối với tôi đó là MySQL https://www.mysql.com/products/connector/ ). Sử dụng hương vị của bạn ở đây.
  • Giải nén tệp jar đã cho trong cùng thư mục với dự án java của bạn. Bạn sẽ nhận được một cấu trúc thư mục như thế này. Nếu bạn xem xét cẩn thận, điều này chính xác liên quan đến những gì chúng tôi cố gắng thực hiện bằng cách sử dụng Class.forName(....). Tệp mà chúng tôi muốn làcom/mysql/jdbc/Driver.class

https://i.imgur.com/VgpwatQ.png

  • Biên dịch chương trình java có chứa mã.
javac App.java
  • Bây giờ tải đạo diễn dưới dạng mô-đun bằng cách chạy
java --module-path com/mysql/jdbc -cp ./ App

Thao tác này sẽ tải gói (đã giải nén) theo cách thủ công và chương trình java của bạn sẽ tìm thấy lớp Trình điều khiển cần thiết.


  • Lưu ý rằng điều này được thực hiện cho mysqltrình điều khiển, các trình điều khiển khác có thể yêu cầu những thay đổi nhỏ.
  • Nếu nhà cung cấp của bạn cung cấp .debhình ảnh, bạn có thể lấy lọ từ/usr/share/java/your-vendor-file-here.jar

-1

Tôi gặp phải sự cố này do đặt src/main/resourcesnhầm tệp XML , tôi đã xóa tệp đó và sau đó tất cả trở lại bình thường.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.