У меня в одном каталоге два класса - тестовый и основной. Оба должны подключаться к базе данных через драйвер JDBC, который подключается через pom.xml.

У классов одинаковые настройки подключения, но тестовый класс работает нормально, а основной класс выдает исключение ClassNotFoundException: com.mysql.jdbc.Driver. Пробовал разные варианты коннектора, сейчас он самый свежий (8.0.12).

Еще пробовал вручную добавить jar-файл с драйвером - ситуация повторилась. Больше никаких идей.

Тестовый класс:

package app.model;

import app.entities.StandartGame;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

public class DBTest {

private static final String USERNAME = "root";
private static final String PASSWORD = "root";
private static final String DATABASEURL = "jdbc:mysql://localhost:3306/test?serverTimezone=Europe/Moscow&useSSL=false";

public static void main(String[] args) {

    try {
        Class.forName("com.mysql.cj.jdbc.Driver");
        Connection connection = DriverManager.getConnection(DATABASEURL, USERNAME, PASSWORD);
        Statement statement = connection.createStatement();

        String thisName, thisGenre;
        double thisPrice;

        ResultSet resultSet = statement.executeQuery("select * from GameShop");
        List<StandartGame> games = new ArrayList<StandartGame>();

        while (resultSet.next()) {
            thisPrice = resultSet.getDouble("price");
            thisName = resultSet.getString("name");
            thisGenre = resultSet.getString("genre");

            StandartGame game = new StandartGame(thisName, thisPrice, thisGenre);
            games.add(game);
        }

        for (StandartGame game: games) {
            System.out.println(game.getName());
        }


    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    } catch (SQLException e) {
        e.printStackTrace();
    }
  }
}

Основной класс:

package app.model;

import app.entities.StandartGame;
import java.sql.*;
import java.util.List;

public class SingletonModel {

private static SingletonModel model;

private static final String USERNAME = "root";
private static final String PASSWORD = "root";
private static final String DATABASEURL = "jdbc:mysql://localhost:3306/test?serverTimezone=Europe/Moscow&useSSL=false";

public static String driverPath = "com.mysql.cj.jdbc.Driver";
public static Connection connection;
public static Statement statement;

public static synchronized void addGames(StandartGame ... gamez) {
    try {

        Class.forName(driverPath);
        connection = DriverManager.getConnection(DATABASEURL, USERNAME, PASSWORD);
        statement = connection.createStatement();

        String thisName, thisGenre;
        double thisPrice;

        for (StandartGame stg : gamez) {
            thisName = stg.getName();
            thisGenre = stg.getGenre();
            thisPrice = stg.getPrice();
            statement.executeUpdate("insert into GameShop (name, genre, price) VALUE " +
                    "('"+thisName+"', '"+thisGenre+"', '"+thisPrice+"')");
        }

    } catch (Exception e) {
        e.printStackTrace();
    }
}

java.lang.ClassNotFoundException: com.mysql.cj.jdbc.Driver
at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1309)
at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1138)
at java.base/java.lang.Class.forName0(Native Method)
at java.base/java.lang.Class.forName(Class.java:291)
at app.model.SingletonModel.addGames(SingletonModel.java:50)
at app.servlets.AddServlet.doPost(AddServlet.java:35)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:660)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:199)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:490)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:668)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:408)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:770)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1415)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1135)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.base/java.lang.Thread.run(Thread.java:844)
2
anabioze 14 Окт 2018 в 22:25

1 ответ

Лучший ответ

Это почти наверняка связано с тем, как вы настроили код, а не с самим кодом. Исключение исходит от Class.forName, и использование diff показывает, что строки, которые вы процитировали, совпадают (без скрытых гомоглифов или других опечаток).

Типичный подход - попробовать простейшее, что пока не удается. Минимальный, полный и поддающийся проверке пример - это местный термин Stack Overflow для этого.

Замена всего кода примера на это должна показать проблему без всякой другой ерунды. Вы можете использовать точно такой же код со встроенной литеральной строкой с копированием и вставкой между ними или напрямую ссылаться на класс.

Class<?> driverClass = com.mysql.cj.jdbc.Driver.class;

(Возможно, сначала вам придется скорректировать путь к классам для компилятора исходного кода Java.) Обычно это можно заменить путем непосредственного создания драйвера.

java.sql.Driver driver = new com.mysql.cj.jdbc.Driver();

Мы превратили ошибку времени выполнения в ошибку времени компиляции. Выиграть! Что ж, в этом случае это, вероятно, закончится ошибкой времени ссылки.

Что бы там ни было, после этого отклонения исключение показывает, что существует проблема с classpath во время выполнения. Это может быть что-то в pom.xml - драйвер MySQL должен быть виден в пути к классам для запуска веб-приложения.

Вы можете развернуть классы библиотеки вместе с кодом своего веб-приложения. В качестве альтернативы есть другие стандартные места для размещения библиотек в веб-контейнерах (см. Вашу документацию), которые можно использовать более широко и устранить накладные расходы на перезагрузку драйверов при повторном развертывании в работающем контейнере во время разработки. Драйверы JDBC - это просто библиотеки классов в jar-файлах (некоторые из них имеют собственные компоненты, но я считаю, что в наши дни это в значительной степени ограничивается изворотливыми мостами к собственным интерфейсам).

1
Tom Hawtin - tackline 14 Окт 2018 в 20:43