臭名昭著的java.sql.SQLException:找不到合适的驱动程序


89

我正在尝试将启用数据库的JSP添加到现有的Tomcat 5.5应用程序(GeoServer 2.0.0,如果有帮助的话)。

该应用程序本身与Postgres可以很好地进行通信,因此我知道数据库已启动,用户可以访问它,所有这些好东西。我正在尝试做的是添加的JSP中的数据库查询。我已经在开箱即用的Tomcat数据源示例中使用了config示例。必需的标记库位于正确的位置-如果我只有标记库引用,则不会发生任何错误,因此它将查找那些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]

Answers:


106

臭名昭著的java.sql.SQLException:找不到合适的驱动程序

这个异常基本上可以有两个原因:

1. JDBC驱动程序未加载

您需要确保将JDBC驱动程序放置在服务器自己的/lib文件夹中。

或者,当您实际上不使用服务器管理的连接池数据源,而是DriverManager#getConnection()在WAR中手动摆弄时,则需要将JDBC驱动程序放在WAR中/WEB-INF/lib并执行..

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

..在首次调用之前的代码中DriverManager#getConnection(),请确保不要吞下/忽略ClassNotFoundException它可能抛出的任何内容,并继续执行代码流,就好像没有发生任何异常情况一样。另请参见在哪里必须为Tomcat的连接池放置JDBC驱动程序?

2.或者,JDBC URL的语法错误

您需要确保JDBC URL符合JDBC驱动程序文档,并记住它通常区分大小写。当JDBC URL不返回trueDriver#acceptsURL()对任何加载的驱动程序,那么你也将获得正是这种例外。

如果是PostgreSQL,请在此处记录

使用JDBC,数据库由URL(统一资源定位符)表示。对于PostgreSQL™,这采用以下形式之一:

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

如果是MySQL,请在此处记录

用于连接到MySQL服务器的JDBC URL的一般格式如下,方括号([ ])中的项目是可选的:

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

如果是Oracle,请在此处记录

URL语法有2种,旧语法仅适用于SID,新语法具有Oracle服务名称。

旧语法 jdbc:oracle:thin:@[HOST][:PORT]:SID

新语法 jdbc:oracle:thin:@//[HOST][:PORT]/SERVICE


也可以看看:


谢谢你们!抱歉,第一次尝试不在OP中,只是jdbc:postgresql:mmas(我尝试了其他尝试!)。可悲的是,使用araqnid的URL,结果相同。昨晚我用tablib替换了(ick)嵌入式Java,效果很好:尝试{Class.forName(“ org.postgresql.Driver”)。newInstance(); con = DriverManager.getConnection(“ jdbc:postgresql:mmas”,“ mmas”,“ passwd”); stmt = con.createStatement(); rs = stmt.executeQuery(“ select yada yada”); if(rs!= null && rs.next()){//获得名望,财富,荣耀,辣妹雅加达的例子是带有标签库的,所以我从那开始。
里克·韦恩

啊。注释不是很多,带有代码格式。啊 我的新手正在显示吗?(ZIIP!)无论如何,Jakarta的示例都是关于使用<sql:query>语法而不是仅仅嵌入Java代码,而且我同意这是一种更清洁的方法。不需要显式调用forName()和getConnection()吧?但是,旧的丑陋的在表示层中破解驱动程序代码的方法工作得很好,首先尝试一下。因此,我感到困惑,但现在更多的是维护/美学问题,而不是“这已被破坏,修复或提高了汉堡翻转技巧”。
里克·韦恩

恕我直言,使用sql taglib的脚本只比在scriptlet中执行JDBC更好。虽然每个都有,并使用sql:query使事情变得简单:)(ish)
araqnid

我从未说过我同意使用JSTL SQL taglib,但这不是本主题的主题。
BalusC

2
谢谢,您的JDBC连接字符串格式非常有帮助!
杰伊·泰勒

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

该网址看起来不正确,您需要以下内容吗?

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

15

我忘记将PostgreSQL JDBC驱动程序添加到我的项目(Mvnrepository)中。

摇篮

// 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驱动程序异常:找不到合适的驱动程序

通过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),然后选中底部的“取消阻止”框来解决此问题。

Windows JAR文件属性对话框
Windows JAR文件属性对话框


1

除了添加MySQL JDBC连接器之外,还要确保将带有数据库连接定义的context.xml(如果未在Tomcat webapps文件夹中解压)包含在Tomcats conf目录中。


1

可能导致的一个非常愚蠢的错误是在JDBC URL连接开始时增加了空间。

我的意思是:-

假设您给jdbc url带来了错误,例如

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

(请注意,URL的注视中有空格,这将导致错误)

正确的方法应该是:

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

在STS中开发Spring Boot应用程序时遇到了这个确切的问题,但是最终将打包的war部署到WebSphere(v.9)。根据先前的回答,我的情况很独特。ojdbc8.jar放在我的WEB-INF / lib文件夹中,并且设置了Parent Last类加载,但始终说它找不到合适的驱动程序。

我的最终问题是我使用了不正确的DataSource类,因为我只是跟随在线教程/示例一起学习。感谢David Dai在这里对自己的问题的评论,找到了提示:Spring JDBC无法加载JDBC驱动程序类[oracle.jdbc.driver.OracleDriver]

后来还发现了使用Oracle特定驱动程序的spring guru示例: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;
    }
}

和更正的示例使用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

我在使用Spring数据的mysql数据源中遇到了同样的问题,该问题可以在外部工作,但是在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驱动程序文件的路径在哪里(例如,用于SQL Server的JDBC))。

ConnectURL是从驱动器(示例应用程序samples/connections/ConnectURL.java通过编译), javac ConnectURL.java


0

就我而言,我正在使用Maven处理Java项目,并遇到了此错误。在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.forNameDriverManager应该能够找到它。
Stephen C

你或许是正确的。Java不是我的主要编码语言。
布林格

0

如果没有在应用程序的某个位置提供资源定义,则可能会遇到相同的错误-很可能是在中央context.xml中,或者在conf / Catalina / localhost中的单个上下文文件中。而且,如果使用单个上下文文件,请注意,只要您删除/取消部署相应的.war文件,Tomcat就会自由删除它们。


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
  • 现在,通过运行将Director加载为模块
java --module-path com/mysql/jdbc -cp ./ App

这将手动加载(提取的)程序包,并且您的Java程序将找到所需的Driver类。


  • 请注意,此操作已针对mysql驱动程序完成,其他驱动程序可能需要稍作更改。
  • 如果您的供应商提供了.deb图像,则可以从/usr/share/java/your-vendor-file-here.jar

-1

我通过src/main/resources错误地将XML文件放入而遇到了这个问题,我删除了它,然后全部恢复正常。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.