Niesławny java.sql.SQLException: nie znaleziono odpowiedniego sterownika

89

Próbuję dodać stronę JSP z obsługą bazy danych do istniejącej aplikacji Tomcat 5.5 (GeoServer 2.0.0, jeśli to pomaga).

Sama aplikacja dobrze komunikuje się z Postgresem, więc wiem, że baza danych działa, użytkownik ma do niej dostęp i wszystkie te dobre rzeczy. To, co próbuję zrobić, to zapytanie do bazy danych w dodanej przeze mnie stronie JSP. Użyłem przykładu konfiguracji w przykładzie źródła danych Tomcat prawie po wyjęciu z pudełka. Wymagane taglib znajdują się we właściwym miejscu - nie pojawiają się żadne błędy, jeśli mam tylko refs taglib, więc znajduje te pliki JAR. Sterownik postgres jdbc, postgresql-8.4.701.jdbc3.jar, znajduje się w katalogu $ CATALINA_HOME / common / lib.

Oto początek strony 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>

Odpowiednia sekcja z $ CATALINA_HOME / conf / server.xml, wewnątrz <Host>której znajduje się z kolei w <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>

Te wiersze są ostatnimi w tagu w 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>

Wreszcie wyjątek:

   exception
    org.apache.jasper.JasperException: Unable to get connection, DataSource invalid: "java.sql.SQLException: No suitable driver"
    [...wads of ensuing goo elided]
Rick Wayne
źródło
Zobacz moją odpowiedź: stackoverflow.com/a/38656446/632951
Pacerier

Odpowiedzi:

106

Niesławny java.sql.SQLException: nie znaleziono odpowiedniego sterownika

Ten wyjątek może mieć zasadniczo dwie przyczyny:

1. Sterownik JDBC nie jest załadowany

Musisz upewnić się, że sterownik JDBC znajduje się we własnym /libfolderze serwera .

Lub, gdy w rzeczywistości nie używasz źródła danych puli połączeń zarządzanych przez serwer, ale ręcznie manipulujesz DriverManager#getConnection()w WAR, musisz umieścić sterownik JDBC w WAR /WEB-INF/libi wykonać ...

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

.. w swoim kodzie przed pierwszym DriverManager#getConnection()wywołaniem, dzięki czemu upewniasz się, że nie połykasz / nie ignorujesz niczego,ClassNotFoundException co może zostać przez niego wyrzucone i kontynuujesz przepływ kodu, jakby nic wyjątkowego się nie wydarzyło. Zobacz także Gdzie muszę umieścić sterownik JDBC dla puli połączeń Tomcat?

2. Lub adres URL JDBC ma nieprawidłową składnię

Musisz upewnić się, że adres URL JDBC jest zgodny z dokumentacją sterownika JDBC i pamiętaj, że zwykle rozróżnia się wielkość liter. Jeśli adres URL JDBC nie powróci truedla Driver#acceptsURL()żadnego z załadowanych sterowników, otrzymasz również dokładnie ten wyjątek.

W przypadku PostgreSQL jest to udokumentowane tutaj .

W JDBC baza danych jest reprezentowana przez adres URL (Uniform Resource Locator). W przypadku PostgreSQL ™ przyjmuje to jedną z następujących form:

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

W przypadku MySQL jest to udokumentowane tutaj .

Ogólny format adresu URL JDBC do łączenia się z serwerem MySQL jest następujący, z elementami w nawiasach kwadratowych ( [ ]) są opcjonalne:

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

W przypadku Oracle jest to udokumentowane tutaj .

Istnieją dwie składnie adresów URL, stara składnia, która działa tylko z identyfikatorem SID, a nowa składnia z nazwą usługi Oracle.

Stara składnia jdbc:oracle:thin:@[HOST][:PORT]:SID

Nowa składnia jdbc:oracle:thin:@//[HOST][:PORT]/SERVICE


Zobacz też:

BalusC
źródło
Dzięki chłopaki! Przepraszamy, pierwsza próba nie była w OP, tylko jdbc: postgresql: mmas (a próbowałem innych!). Niestety, w przypadku adresu URL araqnid ten sam wynik. Zeszłej nocy zamieniłem elementy tablib na (ick) osadzoną Javę i to działa dobrze: spróbuj {Class.forName ("org.postgresql.Driver"). NewInstance (); con = DriverManager.getConnection ("jdbc: postgresql: mmas", "mmas", "passwd"); stmt = con.createStatement (); rs = stmt.executeQuery ("wybierz yada yada"); if (rs! = null && rs.next ()) {// zbieraj sławę, fortunę, chwałę, niemowlęta Przykład Dżakarty był w / taglibs, więc zacząłem w ten sposób.
Rick Wayne
Ach. Komentarze nie tyle z formatowaniem kodu. Ahem. Czy mój nowicjusz się wyświetla? (ZIIP!) W każdym razie w przykładzie z Dżakarty chodziło o użycie składni <sql: query> zamiast po prostu osadzanie kodu Javy i zgadzam się, że jest to znacznie czystszy sposób. Nie powinno być potrzeby jawnego wywoływania forName () i getConnection (), prawda? Ale stara brzydka metoda hack-the-driver-code-in-the-present-layer działała dobrze, najpierw spróbuj. Jestem więc zdziwiony, ale teraz jest to bardziej kwestia konserwacji / estetyki niż „To jest zepsute, napraw lub odświeżyć swoje umiejętności przewracania burgera”.
Rick Wayne
IMHO używanie sql taglib jest tylko trochę lepsze niż robienie JDBC w skryptletach ... o wiele bardziej preferowany jest wzorzec kontrolera / widoku, w którym obsługa db jest wykonywana z góry, a strona JSP po prostu wyświetla. Każdy z własnym, choć i przy użyciu sql: query utrzymuje rzeczy proste :) (ish)
araqnid
Nigdy nie powiedziałem, że zgadzam się z użyciem taglib JSTL SQL, ale to nie jest temat, którego dotyczy ten temat.
BalusC
2
Dzięki, Twoje formaty parametrów połączenia JDBC były niezwykle pomocne!
Jay Taylor
15
url="jdbc:postgresql//localhost:5432/mmas"

Ten adres URL wygląda nieprawidłowo, czy potrzebujesz następujących?

url="jdbc:postgresql://localhost:5432/mmas"
araqnid
źródło
15

Zapomniałem dodać sterownik PostgreSQL JDBC do mojego projektu ( 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>

Można również pobrać z JAR i importu do projektu ręcznie.

Manuel Schmitzberger
źródło
12

Zmierzyłem się z podobnym problemem. Mój projekt w kontekście to Dynamic Web Project (Java 8 + Tomcat 8), a błąd dotyczy sterownika PostgreSQL Wyjątek: Nie znaleziono odpowiedniego sterownika

Zostało to rozwiązane przez dodanie Class.forName("org.postgresql.Driver")przed wywołaniem getConnection()metody

Oto mój przykładowy kod:

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
źródło
3

Poniższa wskazówka okazała się pomocna, aby wyeliminować ten problem w Tomcat -

pamiętaj, aby najpierw załadować sterownik, wykonując Class.forName ("org.postgresql.Driver"); w swoim kodzie.

To jest z postu - https://www.postgresql.org/message-id/[email protected]

Kod jdbc działał dobrze jako samodzielny program, ale w TOMCAT dał błąd - `` Nie znaleziono odpowiedniego sterownika ''

Venkatraman
źródło
Proszę nie link, tylko odpowiedzi - opisz krótko, co się za tym kryje!
monamona
Link do rozwiązania jest mile widziany, ale upewnij się, że Twoja odpowiedź jest przydatna bez niego: dodaj kontekst wokół linku, aby inni użytkownicy mieli pojęcie, co to jest i dlaczego się tam znajduje, a następnie zacytuj najbardziej odpowiednią część strony, którą znasz. ponowne łącze w przypadku, gdy strona docelowa jest niedostępna. Odpowiedzi, które są niewiele więcej niż linkiem, mogą zostać usunięte .
Peter
1

Warto zauważyć, że może to również wystąpić, gdy system Windows blokuje pobieranie, które uważa za niebezpieczne. Można temu zaradzić, klikając prawym przyciskiem myszy plik jar (na przykład ojdbc7.jar) i zaznaczając pole „Odblokuj” u dołu.

Okno dialogowe Właściwości pliku JAR systemu Windows :
Okno dialogowe Właściwości pliku JAR systemu Windows

user7994072
źródło
1

Oprócz dodania łącznika MySQL JDBC upewnij się, że plik context.xml (jeśli nie został rozpakowany w folderze Tomcat webapps) z definicjami połączeń DB znajduje się w katalogu conf Tomcats.

feistyfawn
źródło
1

Bardzo głupim błędem, który może wyniknąć z dodania spacji na początku połączenia JDBC URL.

Chodzi mi o to że:-

Przypuśćmy, że masz bymistake, podając adres URL jdbc, taki jak

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

(Zauważ, że w wyglądzie adresu URL jest spacja, spowoduje to błąd)

właściwą drogą powinno być:

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

(Zauważ, że nie ma spacji w gapieniu się, możesz zostawić spację na końcu adresu URL, ale możesz tego nie robić)

ankkol2011
źródło
0

Używałem jruby, w moim przypadku stworzyłem w 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'

lub gdziekolwiek jest twój kierowca i to wszystko!

Ale Guro
źródło
0

Miałem dokładnie ten problem podczas tworzenia aplikacji Spring Boot w STS, ale ostatecznie wdrażając wojnę pakietową w WebSphere (v.9). Na podstawie poprzednich odpowiedzi moja sytuacja była wyjątkowa. ojdbc8.jar znajdował się w moim folderze WEB-INF / lib z ustawionym ładowaniem klasy Parent Last, ale zawsze mówi, że nie udało się znaleźć odpowiedniego sterownika.

Mój ostateczny problem polegał na tym, że użyłem nieprawidłowej klasy DataSource, ponieważ po prostu śledziłem wraz z samouczkami / przykładami online. Znalazłem podpowiedź dzięki komentarzowi Davida Dai do jego własnego pytania: Spring JDBC Nie można załadować klasy sterownika JDBC [oracle.jdbc.driver.OracleDriver]

Później znaleziono również przykład guru wiosny ze sterownikiem specyficznym dla Oracle: https://springframework.guru/configuring-spring-boot-for-oracle/

Przykład, który zgłasza błąd using org.springframework.jdbc.datasource.DriverManagerDataSourcena podstawie ogólnych przykładów.

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

I poprawiony przykład przy użyciu 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.
źródło
0

Miałem ten sam problem ze źródłem danych mysql używającym danych wiosennych, które działałyby na zewnątrz, ale dały mi ten błąd po wdrożeniu na tomcat.

Błąd zniknął po dodaniu sterownika jar mysql-connector-java-8.0.16.jar do folderu jres lib / ext

Jednak nie chciałem tego robić w produkcji z obawy przed kolizją z innymi aplikacjami. Wyraźne określenie klasy kierowcy rozwiązało ten problem

    spring.datasource.driver-class-name: com.mysql.cj.jdbc.Driver
Występ
źródło
0

Uruchom javaze CLASSPATHzmienną środowiskową wskazującą na plik JAR sterownika, np

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

Gdzie drivers/mssql-jdbc-6.2.1.jre8.jarjest ścieżka do pliku sterownika (np. JDBC dla SQL Server ).

Jest ConnectURLto przykładowa aplikacja z tego sterownika ( samples/connections/ConnectURL.java), skompilowana za pomocą javac ConnectURL.java.

kenorb
źródło
0

W moim przypadku pracowałem nad projektem Java z Mavenem i napotkałem ten błąd. W pliku pom.xml upewnij się, że masz te zależności

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

a tam, gdzie tworzysz połączenie, masz coś takiego

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;
    }
Justice Bringer
źródło
Nie musisz dzwonić Class.forName. DriverManagerpowinien móc go znaleźć.
Stephen C
Możesz mieć rację. Java nie jest moim głównym językiem programowania.
Justice Bringer
0

Ten sam błąd wystąpi, jeśli gdzieś nie ma definicji zasobu dla Twojej aplikacji - najprawdopodobniej w centralnym pliku context.xml lub indywidualnym pliku kontekstu w conf / Catalina / localhost. A jeśli używasz indywidualnych plików kontekstowych, uważaj, że Tomcat usuwa je swobodnie za każdym razem, gdy usuniesz / cofniesz wdrożenie odpowiedniego pliku .war.

em_bo
źródło
0

Bez względu na to, jak stary jest ten wątek, ludzie nadal będą borykać się z tym problemem.

Mój przypadek: Mam najnowszą (w momencie wysyłania) konfigurację OpenJDK i maven. Wypróbowałem wszystkie metody podane powyżej, bez / poza mavenem, a nawet rozwiązaniami na siostrzanych postach w StackOverflow. Nie używam żadnego IDE ani niczego innego, uruchamiając od samego CLI, aby zademonstrować tylko podstawową logikę.

Oto, co w końcu zadziałało.

  • Pobierz sterownik z oficjalnej strony. (dla mnie był to MySQL https://www.mysql.com/products/connector/ ). Użyj tutaj swojego smaku.
  • Rozpakuj podany plik jar w tym samym katalogu, w którym znajduje się projekt Java. Otrzymałbyś taką strukturę katalogów. Jeśli przyjrzysz się uważnie, to dokładnie odnosi się do tego, co staramy się robić przy użyciu Class.forName(....). Plik, którego potrzebujemy, tocom/mysql/jdbc/Driver.class

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

  • Skompiluj program java zawierający kod.
javac App.java
  • Teraz załaduj reżysera jako moduł, uruchamiając
java --module-path com/mysql/jdbc -cp ./ App

Spowoduje to ręczne załadowanie (rozpakowanego) pakietu, a program java znajdzie wymaganą klasę sterownika.


  • Zauważ, że zostało to zrobione dla mysqlsterownika, inne sterowniki mogą wymagać drobnych zmian.
  • Jeśli sprzedawca dostarcza .debobraz, możesz zdobyć słoik z/usr/share/java/your-vendor-file-here.jar
Yash Kumar Verma
źródło
-1

Napotkałem ten problem, umieszczając plik XML w src/main/resourcesniewłaściwym miejscu, usunąłem go i wszystko wróciło do normy.

jerryleooo
źródło