java.sql.SQLException ที่น่าอับอาย: ไม่พบไดรเวอร์ที่เหมาะสม


90

ฉันกำลังพยายามเพิ่ม JSP ที่เปิดใช้งานฐานข้อมูลลงในแอปพลิเคชัน Tomcat 5.5 ที่มีอยู่ (GeoServer 2.0.0 หากช่วยได้)

ตัวแอปพูดคุยกับ Postgres ได้ดีดังนั้นฉันจึงรู้ว่าฐานข้อมูลพร้อมแล้วผู้ใช้สามารถเข้าถึงได้ทุกสิ่งที่ดี สิ่งที่ฉันพยายามทำคือแบบสอบถามฐานข้อมูลใน JSP ที่ฉันได้เพิ่มเข้าไป ฉันใช้ตัวอย่างการกำหนดค่าในตัวอย่างแหล่งข้อมูล Tomcatนอกกรอบไปแล้ว taglibs ที่จำเป็นอยู่ในตำแหน่งที่ถูกต้อง - ไม่มีข้อผิดพลาดใด ๆ เกิดขึ้นถ้าฉันมี taglib refs ดังนั้นจึงพบ JAR เหล่านั้น ไดรเวอร์ postgres jdbc, postgresql-8.4.701.jdbc3.jar อยู่ใน $ CATALINA_HOME / common / lib

นี่คือด้านบนของ 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>

ส่วนที่เกี่ยวข้องจาก $ CATALINA_HOME / conf / server.xml <Host>ซึ่งอยู่ภายใน<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>

บรรทัดเหล่านี้เป็นบรรทัดสุดท้ายในแท็กใน 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>

สุดท้ายข้อยกเว้น:

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

ดูคำตอบของฉัน: stackoverflow.com/a/38656446/632951
Pacerier

คำตอบ:


109

java.sql.SQLException ที่น่าอับอาย: ไม่พบไดรเวอร์ที่เหมาะสม

ข้อยกเว้นนี้อาจมีสาเหตุสองประการ:

1. ไม่ได้โหลดไดรเวอร์ JDBC

คุณต้องแน่ใจว่าไดร์เวอร์ JDBC ถูกวางไว้ใน/libโฟลเดอร์ของเซิร์ฟเวอร์เอง

หรือเมื่อคุณไม่ได้ใช้แหล่งข้อมูลพูลการเชื่อมต่อที่จัดการโดยเซิร์ฟเวอร์ แต่กำลังเล่นซอด้วยตนเองDriverManager#getConnection()ใน WAR คุณต้องวางไดรเวอร์ JDBC ใน WAR /WEB-INF/libและดำเนินการ ..

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

.. ในรหัสของคุณก่อนการDriverManager#getConnection()โทรครั้งแรกโดยที่คุณต้องแน่ใจว่าคุณจะไม่กลืน / เพิกเฉยต่อสิ่งใด ๆClassNotFoundExceptionที่สามารถโยนทิ้งได้และดำเนินการตามขั้นตอนของรหัสต่อไปราวกับว่าไม่มีอะไรพิเศษเกิดขึ้น ดูเพิ่มเติมฉันต้องวางไดรเวอร์ JDBC สำหรับพูลการเชื่อมต่อของ Tomcat ไว้ที่ไหน

2. หรือ JDBC URL ผิดไวยากรณ์

คุณต้องตรวจสอบให้แน่ใจว่า URL ของ JDBC เป็นไปตามเอกสารคู่มือไดรเวอร์ JDBC และโปรดทราบว่าโดยปกติจะพิจารณาตัวพิมพ์เล็กและใหญ่ เมื่อ JDBC URL ไม่ส่งคืนtrueสำหรับDriver#acceptsURL()ไดรเวอร์ที่โหลดใด ๆ คุณก็จะได้รับข้อยกเว้นนี้เช่นกัน

ในกรณีของPostgreSQLเป็นเอกสารที่นี่

ด้วย JDBC ฐานข้อมูลจะแสดงด้วย URL (Uniform Resource Locator) ด้วย PostgreSQL ™จะใช้รูปแบบใดรูปแบบหนึ่งต่อไปนี้:

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

ในกรณีของMySQLมันเป็นเอกสารที่นี่

รูปแบบทั่วไปสำหรับ JDBC URL สำหรับเชื่อมต่อกับเซิร์ฟเวอร์ MySQL มีดังต่อไปนี้โดยรายการในวงเล็บเหลี่ยม ( [ ]) เป็นทางเลือก:

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

ในกรณีของออราเคิลเป็นเอกสารที่นี่

มีไวยากรณ์ URL 2 รูปแบบไวยากรณ์เก่าซึ่งจะใช้ได้เฉพาะกับ SID และไวยากรณ์ใหม่ที่มีชื่อบริการ Oracle

ไวยากรณ์เก่า jdbc:oracle:thin:@[HOST][:PORT]:SID

ไวยากรณ์ใหม่ jdbc:oracle:thin:@//[HOST][:PORT]/SERVICE


ดูสิ่งนี้ด้วย:


ขอบคุณเพื่อน! ขออภัยความพยายามครั้งแรกไม่ได้อยู่ใน OP เพียงแค่ jdbc: postgresql: mmas (และฉันพยายามอย่างอื่น!) น่าเศร้าด้วย URL ของ araqnid ผลลัพธ์เดียวกัน เมื่อคืนฉันเปลี่ยน tablib สำหรับ (ick) แบบฝัง Java และใช้ได้ดี: ลองใช้ {Class.forName ("org.postgresql.Driver") newInstance (); con = DriverManager.getConnection ("jdbc: postgresql: mmas", "mmas", "passwd"); stmt = con.createStatement (); rs = stmt.executeQuery ("เลือกยาดายาดา"); if (rs! = null && rs.next ()) {// เก็บเกี่ยวชื่อเสียงโชคลาภความรุ่งโรจน์ตัวอย่างของ babes จาการ์ตาคือ w / taglibs ดังนั้นฉันจึงเริ่มแบบนั้น
Rick Wayne

อา. ความคิดเห็นไม่มากนักกับการจัดรูปแบบโค้ด อะแฮ่ม. มือใหม่ของฉันแสดงหรือไม่ (ZIIP!) อย่างไรก็ตามตัวอย่างจาการ์ตานั้นเกี่ยวกับการใช้ไวยากรณ์ <sql: query> แทนการฝังโค้ด Java และฉันยอมรับว่าเป็นวิธีที่สะอาดกว่ามาก เราไม่จำเป็นต้องเรียก forName () และ getConnection () อย่างชัดเจนใช่ไหม? แต่วิธีการแฮ็กไดรเวอร์โค้ดในเลเยอร์การนำเสนอแบบเก่าที่น่าเกลียดใช้งานได้ดีลองก่อน ดังนั้นฉันจึงงงงวย แต่ตอนนี้มันเป็นปัญหาด้านการดูแลรักษา / ความสวยงามมากกว่า "นี่พังแก้ไขได้หรือขัดทักษะการพลิกเบอร์เกอร์ของคุณ"
Rick Wayne

IMHO ที่ใช้ sql taglib นั้นดีกว่าการทำ JDBC ใน scriptlets เพียงเล็กน้อยเท่านั้น ... ชอบรูปแบบคอนโทรลเลอร์ / มุมมองที่สิ่งต่างๆ db ทำตรงหน้าและ JSP จะแสดงสิ่งต่างๆ แต่ละคนเป็นของตัวเองและการใช้ sql: query ทำให้สิ่งต่างๆง่าย :) (ish)
araqnid

ฉันไม่เคยบอกว่าฉันเห็นด้วยกับการใช้ JSTL SQL taglib แต่นั่นไม่ใช่หัวข้อที่เกี่ยวข้องกับหัวข้อนี้
BalusC

2
ขอบคุณรูปแบบสตริงการเชื่อมต่อ JDBC ของคุณมีประโยชน์มาก!
Jay Taylor

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

URL นั้นดูผิดคุณต้องการสิ่งต่อไปนี้หรือไม่

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

15

ฉันลืมเพิ่ม PostgreSQL JDBC Driver ลงในโปรเจ็กต์ของฉัน ( 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>

นอกจากนี้คุณยังสามารถดาวน์โหลดJARและนำเข้ากับโครงการของคุณด้วยตนเอง


12

ฉันประสบปัญหาที่คล้ายกัน โครงการของฉันในบริบทคือ Dynamic Web Project (Java 8 + Tomcat 8) และข้อผิดพลาดสำหรับข้อยกเว้นของ PostgreSQL Driver: ไม่พบไดรเวอร์ที่เหมาะสม

ได้รับการแก้ไขโดยการเพิ่มClass.forName("org.postgresql.Driver")ก่อนgetConnection()วิธีการโทร

นี่คือรหัสตัวอย่างของฉัน:

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

ฉันพบว่าเคล็ดลับ followig มีประโยชน์ในการขจัดปัญหานี้ใน Tomcat -

อย่าลืมโหลดไดรเวอร์ก่อนโดยทำ Class.forName ("org.postgresql.Driver"); ในรหัสของคุณ

มาจากโพสต์ - https://www.postgresql.org/message-id/e13c14ec050510103846db6b0e@mail.gmail.com

รหัส jdbc ทำงานได้ดีในฐานะโปรแกรมแบบสแตนด์อโลน แต่ใน TOMCAT ให้ข้อผิดพลาด - 'ไม่พบไดรเวอร์ที่เหมาะสม'


โปรดอย่าเชื่อมโยงคำตอบเท่านั้น - อธิบายสั้น ๆ ว่ามีอะไรอยู่เบื้องหลัง!
monamona

ยินดีต้อนรับลิงก์ไปยังโซลูชัน แต่โปรดตรวจสอบให้แน่ใจว่าคำตอบของคุณมีประโยชน์หากไม่มีมัน: เพิ่มบริบทรอบ ๆ ลิงก์เพื่อให้ผู้ใช้เพื่อนของคุณมีความคิดว่ามันคืออะไรและทำไมจึงอยู่ที่นั่นจากนั้นอ้างถึงส่วนที่เกี่ยวข้องที่สุดของเพจ การเชื่อมโยงอีกครั้งในกรณีที่หน้าเป้าหมายไม่พร้อมใช้งาน คำตอบที่มีน้อยกว่าการเชื่อมโยงอาจถูกลบออก
ปีเตอร์

1

อาจเป็นที่น่าสังเกตว่าสิ่งนี้อาจเกิดขึ้นได้เมื่อ Windows บล็อกการดาวน์โหลดที่พิจารณาว่าไม่ปลอดภัย แก้ไขได้โดยคลิกขวาที่ไฟล์ jar (เช่น ojdbc7.jar) แล้วเลือกช่อง "Unblock" ที่ด้านล่าง

กล่องโต้ตอบคุณสมบัติไฟล์ Windows JAR :
กล่องโต้ตอบคุณสมบัติไฟล์ Windows JAR


1

เช่นเดียวกับการเพิ่มตัวเชื่อมต่อ MySQL JDBC ให้แน่ใจว่า context.xml (หากไม่ได้คลายแพ็กในโฟลเดอร์ Tomcat webapps) ที่มีข้อกำหนดการเชื่อมต่อ DB ของคุณจะรวมอยู่ในไดเร็กทอรี Tomcats conf


1

ข้อผิดพลาดที่โง่มากซึ่งอาจเป็นไปได้คือการเพิ่มช่องว่างที่จุดเริ่มต้นของการเชื่อมต่อ JDBC URL

ที่ฉันหมายถึงคือ:-

สมมติว่าคุณมี bymistake ให้ jdbc url เช่น

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

(สังเกตว่ามีช่องว่างในการจ้อง url ซึ่งจะทำให้ error)

วิธีที่ถูกต้องควรเป็น:

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

(สังเกตว่าไม่มีช่องว่างในการจ้องคุณอาจให้ที่ว่างท้าย url แต่ก็ไม่ปลอดภัย)


0

ฉันใช้ jruby ในกรณีของฉันฉันสร้างภายใต้ config / initializers

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'

หรือไม่ว่าคนขับของคุณจะอยู่ที่ไหนก็ตาม!


0

ฉันมีปัญหานี้อย่างแน่นอนเมื่อพัฒนาแอปพลิเคชัน Spring Boot ใน STS แต่ท้ายที่สุดแล้วการปรับใช้สงครามแพ็กเกจกับ WebSphere (v.9) จากคำตอบก่อนหน้านี้สถานการณ์ของฉันไม่เหมือนใคร ojdbc8.jar อยู่ในโฟลเดอร์ WEB-INF / lib ของฉันพร้อมชุดการโหลดคลาส Parent Last แต่มักจะบอกว่าไม่พบไดรเวอร์ที่เหมาะสม

ปัญหาสุดท้ายของฉันคือฉันใช้คลาส DataSource ที่ไม่ถูกต้องเพราะฉันเพิ่งทำตามบทเรียน / ตัวอย่างออนไลน์ พบคำใบ้ขอบคุณความคิดเห็นของ David Dai ในคำถามของเขาเองที่นี่: Spring JDBC ไม่สามารถโหลดคลาสไดรเวอร์ JDBC [oracle.jdbc.driver.OracleDriver]

นอกจากนี้ยังพบตัวอย่าง Spring guru พร้อมไดรเวอร์เฉพาะของ Oracle: https://springframework.guru/configuring-spring-boot-for-oracle/

ตัวอย่างที่แสดงข้อผิดพลาดโดยใช้org.springframework.jdbc.datasource.DriverManagerDataSourceตามตัวอย่างทั่วไป

@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;
    }
}

และ exapmle ที่แก้ไขโดยใช้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

ฉันมีปัญหาเดียวกันกับ mysql datasource โดยใช้ข้อมูลสปริงที่จะทำงานภายนอก แต่ให้ข้อผิดพลาดนี้เมื่อปรับใช้กับ tomcat

ข้อผิดพลาดหายไปเมื่อฉันเพิ่ม jar ไดรเวอร์ mysql-connector-java-8.0.16.jar ลงในโฟลเดอร์ jres lib / ext

อย่างไรก็ตามฉันไม่ต้องการทำสิ่งนี้ในการผลิตเพราะกลัวว่าจะรบกวนการใช้งานอื่น ๆ ความชัดเจนในการกำหนดคลาสไดรเวอร์ช่วยแก้ปัญหานี้ให้ฉัน

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

0

เรียกใช้javaโดยCLASSPATHตัวแปรสภาพแวดล้อมที่ชี้ไปที่ไฟล์ JAR ของไดรเวอร์เช่น

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

drivers/mssql-jdbc-6.2.1.jre8.jarพา ธ ไปยังไฟล์ไดรเวอร์อยู่ที่ไหน(เช่นJDBC สำหรับ SQL Server )

ConnectURLคือการตรวจสอบตัวอย่างจากโปรแกรมควบคุมที่ ( samples/connections/ConnectURL.java) javac ConnectURL.javaรวบรวมผ่าน


0

ในกรณีของฉันฉันกำลังทำงานกับโปรเจ็กต์ Java กับ Maven และพบข้อผิดพลาดนี้ ในไฟล์ pom.xml ของคุณให้แน่ใจว่าคุณมีการอ้างอิงนี้

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

และจุดที่คุณสร้างการเชื่อมต่อมีลักษณะเช่นนี้

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

Class.forNameคุณไม่ควรจะต้องโทร DriverManagerน่าจะหาได้
Stephen C

คุณอาจจะคิดถูก Java ไม่ใช่ภาษาเข้ารหัสหลักของฉัน
Justice Bringer

0

คุณจะได้รับข้อผิดพลาดเดียวกันนี้หากไม่มีคำจำกัดความทรัพยากรที่ระบุไว้ที่ใดที่หนึ่งสำหรับแอปของคุณซึ่งส่วนใหญ่จะอยู่ใน context.xml ส่วนกลางหรือไฟล์บริบทแต่ละไฟล์ใน conf / Catalina / localhost และหากใช้ไฟล์บริบทแต่ละไฟล์โปรดระวังว่า Tomcat จะลบไฟล์เหล่านั้นได้อย่างอิสระเมื่อใดก็ตามที่คุณลบ / เลิกใช้งานไฟล์. war ที่เกี่ยวข้อง


0

ไม่ว่ากระทู้นี้จะเก่าแค่ไหนผู้คนก็ยังคงต้องเผชิญกับปัญหานี้

กรณีของฉัน: ฉันมีการตั้งค่า OpenJDK และ maven ล่าสุด (ในขณะที่โพสต์) ฉันได้ลองใช้วิธีการทั้งหมดที่ระบุข้างต้นด้วย / ออก maven และแม้แต่วิธีแก้ปัญหาในโพสต์ของพี่สาวใน StackOverflow ฉันไม่ได้ใช้ IDE หรือสิ่งอื่นใดโดยเรียกใช้จาก CLI เปล่าเพื่อแสดงเฉพาะตรรกะหลักเท่านั้น

นี่คือสิ่งที่ได้ผลในที่สุด

  • ดาวน์โหลดไดรเวอร์จากเว็บไซต์ทางการ (สำหรับฉันมันคือ MySQL https://www.mysql.com/products/connector/ ) ใช้รสชาติของคุณที่นี่
  • แตกไฟล์ jar ที่กำหนดในไดเร็กทอรีเดียวกับโปรเจ็กต์ java ของคุณ คุณจะได้โครงสร้างไดเรกทอรีเช่นนี้ Class.forName(....)ถ้าคุณมองอย่างนี้ว่าเกี่ยวข้องกับสิ่งที่เราพยายามที่จะทำโดยใช้ ไฟล์ที่เราต้องการคือไฟล์com/mysql/jdbc/Driver.class

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

  • คอมไพล์โปรแกรม java ที่มีโค้ด
javac App.java
  • ตอนนี้โหลดไดเร็กทอรีเป็นโมดูลโดยเรียกใช้
java --module-path com/mysql/jdbc -cp ./ App

สิ่งนี้จะโหลดแพ็คเกจ (แยก) ด้วยตนเองและโปรแกรม java ของคุณจะค้นหาคลาสไดรเวอร์ที่ต้องการ


  • โปรดทราบว่าสิ่งนี้ทำขึ้นสำหรับmysqlไดรเวอร์ไดรเวอร์อื่น ๆ อาจต้องการการเปลี่ยนแปลงเล็กน้อย
  • หากผู้ขายของคุณให้.debภาพคุณจะได้รับโถจาก/usr/share/java/your-vendor-file-here.jar

-1

ฉันพบปัญหานี้จากการใส่ไฟล์ XML src/main/resourcesผิดพลาดฉันลบมันและกลับสู่สภาวะปกติ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.