La infame java.sql.SQLException: no se encontró un controlador adecuado

89

Estoy tratando de agregar una JSP habilitada para base de datos a una aplicación Tomcat 5.5 existente (GeoServer 2.0.0, si eso ayuda).

La aplicación en sí habla con Postgres muy bien, así que sé que la base de datos está activa, el usuario puede acceder a ella, todas esas cosas buenas. Lo que estoy tratando de hacer es una consulta de base de datos en una JSP que he agregado. He usado el ejemplo de configuración en el ejemplo de fuente de datos de Tomcat prácticamente listo para usar . Los taglibs necesarios están en el lugar correcto; no se producen errores si solo tengo las referencias de taglib, por lo que es encontrar esos JAR. El controlador jdbc de postgres, postgresql-8.4.701.jdbc3.jar está en $ CATALINA_HOME / common / lib.

Aquí está la parte superior de la 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>

La sección relevante de $ CATALINA_HOME / conf / server.xml, dentro de la <Host>cual está a su vez dentro <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>

Estas líneas son las últimas en la etiqueta en 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>

Finalmente, la excepción:

   exception
    org.apache.jasper.JasperException: Unable to get connection, DataSource invalid: "java.sql.SQLException: No suitable driver"
    [...wads of ensuing goo elided]
Rick Wayne
fuente
Vea mi respuesta: stackoverflow.com/a/38656446/632951
Pacerier

Respuestas:

106

La infame java.sql.SQLException: no se encontró un controlador adecuado

Esta excepción puede tener básicamente dos causas:

1. El controlador JDBC no está cargado

Debe asegurarse de que el controlador JDBC esté ubicado en la /libcarpeta del servidor .

O, cuando en realidad no está utilizando una fuente de datos de grupo de conexiones administrada por el servidor, pero está manipulando manualmente DriverManager#getConnection()en WAR, entonces debe colocar el controlador JDBC en WAR /WEB-INF/liby realizar ...

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

.. en su código antes de la primera DriverManager#getConnection()llamada, por lo que se asegura de no tragar / ignorar ninguno ClassNotFoundExceptionque pueda arrojar y continuar con el flujo del código como si no hubiera ocurrido nada excepcional. Consulte también ¿Dónde tengo que colocar el controlador JDBC para el grupo de conexiones de Tomcat?

2. O bien, la URL de JDBC tiene una sintaxis incorrecta

Debe asegurarse de que la URL de JDBC se ajuste a la documentación del controlador JDBC y tenga en cuenta que generalmente distingue entre mayúsculas y minúsculas. Cuando la URL de JDBC no regresa truepara Driver#acceptsURL()ninguno de los controladores cargados, también obtendrá exactamente esta excepción.

En el caso de PostgreSQL , está documentado aquí .

Con JDBC, una base de datos está representada por una URL (Localizador uniforme de recursos). Con PostgreSQL ™, esto toma una de las siguientes formas:

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

En el caso de MySQL , está documentado aquí .

El formato general de una URL de JDBC para conectarse a un servidor MySQL es el siguiente, [ ]siendo opcionales los elementos entre corchetes ( ):

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

En el caso de Oracle , está documentado aquí .

Hay 2 sintaxis de URL, sintaxis antigua que solo funcionará con SID y la nueva con el nombre de servicio de Oracle.

Sintaxis antigua jdbc:oracle:thin:@[HOST][:PORT]:SID

Nueva sintaxis jdbc:oracle:thin:@//[HOST][:PORT]/SERVICE


Ver también:

BalusC
fuente
¡Gracias chicos! Lo siento, el primer intento no estaba en OP, solo jdbc: postgresql: mmas (¡y probé otros!). Lamentablemente, con la URL de araqnid, el mismo resultado. Anoche cambié cosas tablib por (ick) Java incrustado, y eso funciona bien: prueba {Class.forName ("org.postgresql.Driver"). NewInstance (); con = DriverManager.getConnection ("jdbc: postgresql: mmas", "mmas", "passwd"); stmt = con.createStatement (); rs = stmt.executeQuery ("seleccione yada yada"); if (rs! = null && rs.next ()) {// cosechar fama, fortuna, gloria, chicas El ejemplo de Yakarta fue w / taglibs, así que comencé de esa manera.
Rick Wayne
¡Ah! Comentarios no tanto con el formato del código. Ejem. ¿Aparece mi novato? (¡ZIIP!) De todos modos, el ejemplo de Yakarta se trataba de usar la sintaxis <sql: query> en lugar de simplemente incrustar código Java, y estoy de acuerdo en que es una forma mucho más limpia de hacerlo. Uno no debería necesitar llamar explícitamente a forName () y getConnection (), ¿verdad? Pero el viejo y feo método hack-the-driver-code-in-the-presentation-layer funcionó bien, primer intento. Estoy desconcertado, pero ahora es más un problema de mantenimiento / estética que "Esto está roto, arréglalo o repasa tus habilidades para voltear hamburguesas".
Rick Wayne
En mi humilde opinión, usar sql taglib es solo un poco mejor que hacer JDBC en scriptlets ... prefiero un patrón de controlador / vista donde las cosas de la base de datos se realizan por adelantado y la JSP solo muestra cosas. Sin embargo, cada uno por su cuenta, y el uso de sql: query mantiene las cosas simples :) (ish)
araqnid
Nunca he dicho que estoy de acuerdo con el uso de JSTL SQL taglib, pero ese no es el tema del que trata este tema.
BalusC
2
Gracias, sus formatos de cadena de conexión JDBC fueron extremadamente útiles.
Jay Taylor
15
url="jdbc:postgresql//localhost:5432/mmas"

Esa URL se ve mal, ¿necesita lo siguiente?

url="jdbc:postgresql://localhost:5432/mmas"
arácnido
fuente
15

Olvidé agregar el controlador JDBC de PostgreSQL en mi proyecto ( 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>

También puede descargar el JAR e importarlo a su proyecto manualmente.

Manuel Schmitzberger
fuente
12

Me enfrenté a un problema similar. Mi proyecto en contexto es Dynamic Web Project (Java 8 + Tomcat 8) y el error es para la excepción del controlador PostgreSQL: no se encontró un controlador adecuado

Se resolvió agregando Class.forName("org.postgresql.Driver")antes de llamar al getConnection()método

Aquí está mi código de muestra:

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());
        }
Vinayak Singh
fuente
3

Encontré el siguiente consejo útil para eliminar este problema en Tomcat:

asegúrese de cargar el controlador primero haciendo un Class.forName ("org.postgresql.Driver"); en su código.

Esto es de la publicación: https://www.postgresql.org/message-id/[email protected]

El código jdbc funcionó bien como programa independiente pero, en TOMCAT, dio el error -'No se encontró un controlador adecuado '

Un Venkatraman
fuente
Por favor, no hay enlaces, solo respuestas: ¡describa brevemente lo que hay detrás de eso!
monamona
Un enlace a una solución es bienvenido, pero asegúrese de que su respuesta sea útil sin él: agregue contexto alrededor del enlace para que sus compañeros usuarios tengan una idea de qué es y por qué está allí, luego cite la parte más relevante de la página. está enlazando a en caso de que la página de destino no esté disponible. Las respuestas que son poco más que un enlace pueden eliminarse .
Peter
1

Vale la pena señalar que esto también puede ocurrir cuando Windows bloquea descargas que considera inseguras. Esto se puede solucionar haciendo clic derecho en el archivo jar (como ojdbc7.jar) y marcando la casilla 'Desbloquear' en la parte inferior.

Cuadro de diálogo Propiedades del archivo JAR de Windows :
Cuadro de diálogo Propiedades del archivo JAR de Windows

usuario7994072
fuente
1

Además de agregar el conector MySQL JDBC, asegúrese de que el context.xml (si no está descomprimido en la carpeta de aplicaciones web de Tomcat) con sus definiciones de conexión de base de datos se incluyan en el directorio conf de Tomcats.

feistyfawn
fuente
1

Un error muy tonto que podría resultar es la adición de espacio al comienzo de la conexión URL de JDBC.

Lo que quiero decir es:-

suponga que ha cometido un error dado la url jdbc como

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

(Observe que hay un espacio en el inicio de la URL, esto producirá el error)

la forma correcta debería ser:

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

(Observe que no hay espacio en la mirada fija, puede dar espacio al final de la URL, pero es seguro no hacerlo)

ankkol2011
fuente
0

Estaba usando jruby, en mi caso lo creé bajo 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'

o donde sea que esté su conductor, ¡y eso es todo!

Ale Guro
fuente
0

Tuve este problema exacto al desarrollar una aplicación Spring Boot en STS, pero finalmente implementé la guerra empaquetada en WebSphere (v.9). Según las respuestas anteriores, mi situación era única. ojdbc8.jar estaba en mi carpeta WEB-INF / lib con el conjunto de carga de la última clase principal, pero siempre dice que no pudo encontrar el controlador adecuado.

Mi problema final fue que estaba usando la clase DataSource incorrecta porque solo estaba siguiendo los tutoriales / ejemplos en línea. Encontré la pista gracias al comentario de David Dai sobre su propia pregunta aquí: Spring JDBC No se pudo cargar la clase de controlador JDBC [oracle.jdbc.driver.OracleDriver]

También se encontró más tarde un ejemplo de Spring Guru con controlador específico de Oracle: https://springframework.guru/configuring-spring-boot-for-oracle/

Ejemplo que arroja error usando org.springframework.jdbc.datasource.DriverManagerDataSourcebasado en ejemplos genéricos.

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

Y el ejemplo corregido usando un 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;
    }
}
Ryan D
fuente
0

Estaba teniendo el mismo problema con la fuente de datos mysql usando datos de primavera que funcionarían afuera, pero me dio este error cuando se implementó en tomcat.

El error desapareció cuando agregué el controlador jar mysql-connector-java-8.0.16.jar a la carpeta jres lib / ext

Sin embargo, no quería hacer esto en producción por temor a interferir con otras aplicaciones. La definición explícita de la clase de controlador resolvió este problema para mí

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

Ejecutar javacon CLASSPATHla variable de entorno apuntando al archivo JAR del controlador, por ejemplo

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

¿Dónde drivers/mssql-jdbc-6.2.1.jre8.jarestá la ruta al archivo del controlador (por ejemplo, JDBC para SQL Server )?

El ConnectURLes la aplicación de ejemplo de que el conductor ( samples/connections/ConnectURL.java), compilado a través javac ConnectURL.java.

Kenorb
fuente
0

En mi caso, estaba trabajando en un proyecto Java con Maven y encontré este error. En su archivo pom.xml asegúrese de tener estas dependencias

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

y donde creas la conexión tienes algo como esto

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;
    }
Portador de justicia
fuente
No debería necesitar llamar Class.forName. DriverManagerdebería poder encontrarlo.
Stephen C
Puede que tengas razón. Java no es mi principal lenguaje de codificación.
Justice Bringer
0

Obtendrá este mismo error si no se proporciona una definición de recurso en algún lugar para su aplicación, probablemente en el context.xml central o en el archivo de contexto individual en conf / Catalina / localhost. Y si utiliza archivos de contexto individuales, tenga en cuenta que Tomcat los elimina libremente cada vez que elimina o anula la implementación del archivo .war correspondiente.

em_bo
fuente
0

No importa qué tan antiguo sea este hilo, la gente continuará enfrentándose a este problema.

Mi caso: Tengo la última configuración (en el momento de la publicación) de OpenJDK y maven. Probé todos los métodos dados anteriormente, sin maven e incluso soluciones en publicaciones hermanas en StackOverflow. No estoy usando ningún IDE ni nada más, ejecutándome desde CLI simple para demostrar solo la lógica central.

Esto es lo que finalmente funcionó.

  • Descargue el controlador del sitio oficial. (para mí fue MySQL https://www.mysql.com/products/connector/ ). Usa tu sabor aquí.
  • Descomprima el archivo jar proporcionado en el mismo directorio que su proyecto java. Obtendría una estructura de directorio como esta. Si observa detenidamente, esto se relaciona exactamente con lo que intentamos hacer con Class.forName(....). El archivo que queremos es elcom/mysql/jdbc/Driver.class

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

  • Compile el programa java que contiene el código.
javac App.java
  • Ahora cargue el director como un módulo ejecutando
java --module-path com/mysql/jdbc -cp ./ App

Esto cargaría el paquete (extraído) manualmente y su programa java encontraría la clase de controlador requerida.


  • Tenga en cuenta que esto se hizo para el mysqlcontrolador, otros controladores pueden requerir cambios menores.
  • Si su proveedor proporciona una .debimagen, puede obtener el frasco en/usr/share/java/your-vendor-file-here.jar
Yash Kumar Verma
fuente
-1

Encontré este problema al colocar un archivo XML src/main/resourcesincorrectamente, lo eliminé y luego todo volvió a la normalidad.

jerryleooo
fuente