我在一个目录中有两个类 - test 和 main。两者都必须通过 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)
最佳答案
这几乎肯定与您配置代码的方式有关,而不是代码本身。异常来自 Class.forName
并使用 diff
显示您引用的字符串是相同的(其中没有偷偷摸摸的同形文字或其他拼写错误)。
典型的方法是尝试仍然失败的最简单的事情。 Minimal, Complete, and Verifiable example作为本地 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 驱动程序必须在类路径中可见才能运行 Web 应用程序。
您可以将库类与您的网络应用程序代码一起部署。或者,还有其他标准位置可以将库放在 Web 容器中(请参阅您的文档),这些容器可以更广泛地共享,并消除在开发过程中重新部署到正在运行的容器中时重新加载驱动程序的开销。 JDBC 驱动程序只是 jar 中的类库(有些具有 native 组件,但我相信如今这在很大程度上仅限于到 native 接口(interface)的狡猾桥梁)。
关于java - 两个类以不同的方式看待 JDBC 驱动程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52806304/