Maven - java.lang.ClassNotFoundException: com.mysql.jdbc.Driver Maven - java.lang.ClassNotFoundException:com.mysql.jdbc.Driver

11

我有一个基于Maven的Java应用程序,想要连接到MySQL服务器。

我的pom文件中包含:

<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.17</version>
    <type>jar</type>
    <scope>runtime</scope>
</dependency>

使用运行时,因为我想在运行时连接到MySQL服务器 - 我还尝试编译和提供,但没有成功。

SQL代码是标准的:

String dbClass = "com.mysql.jdbc.Driver";

Class.forName(dbClass);
Connection connection = DriverManager.getConnection(dbUrl,
    username, password);
Statement statement = connection.createStatement();
ResultSet resultSet = statement.executeQuery(query);
while (resultSet.next()) {
    String tableName = resultSet.getString(1);
    System.out.println("Table name : " + tableName);
}

当我使用Eclipse运行此代码时,它可以正常工作并打印出表名。但是,当我从maven中生成SNAPSHOT,并通过 java -jar target\File.jar 命令运行后,总是会出现错误:

java.lang.ClassNotFoundException: com.mysql.jdbc.Driver

我该如何让maven编译成功?我运行mvn clean install没有错误并且构建也成功了,只有在执行SNAPSHOT文件时才会出错。MySQL的Jar包已经在我的 .m2库中,我尝试通过mvn命令行将其显式添加,但提示它已经存在。

M2仓库是否在类路径上?当您从IDE启动时,它通常会自动添加,但如果您从命令行启动,则可能需要手动指定。 - Adrian Leonhard
这个Maven插件解决了依赖问题。https://dev59.com/jnRB5IYBdhLWcg3wl4Sc#574650 - Yossarian42
5个回答

17

将作用域更改为 compile

<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.17</version>
    <type>jar</type>
    <scope>compile</scope>
</dependency>

默认情况下,省略作用域定义与其对应的是“which” - 同样适用于类型:

<dependency>
   <groupId>mysql</groupId>
   <artifactId>mysql-connector-java</artifactId>
   <version>5.1.17</version>
</dependency>

请查看此链接:https://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html,以获取有关作用域的详细信息。

以下是您需要了解的快速信息:

您将JDBC驱动程序指定为 runtime 范围。大多数IDE都会忽略这些范围,并将所有依赖项添加到它们的类路径中(例如在eclipse之外运行时使用的类路径)。通过 runtime 范围,您告诉Maven它不必将该依赖项打包到最终的jar文件中,因为执行环境将“在运行时提供该依赖项”。例如,您要么必须在调用jar时手动将其添加到类路径中,要么将范围更改为 compile ,这将导致驱动程序jar文件被打包到您的jar文件中并在运行时可用。


1
谢谢,但我已经尝试过了,没有任何区别。答案如下,我需要使用pom中的插件将依赖项构建到快照中。 - pokero
它肯定会有所不同-检查使用两个范围(*-SNAPSHOT).jar的大小和内容-使用provided范围构建的将不包含驱动程序,比使用compile范围构建的小,因为它将在内部打包驱动程序-jar。您可能想查看此链接http://docs.oracle.com/javase/tutorial/deployment/jar/downman.html,因为也许它只是没有正确添加到您的类路径中。 - JBA
如果您从构建中获取了一个 .exe 文件,那么您应该添加相应的插件定义,因为Maven默认情况下无法打包成exe文件。 - JBA
JBA,我的意思是这没有任何区别,因为缺失的类错误仍然存在。唯一对我起作用的解决方案是构建一个 Uber Pom。 - pokero
你正在使用Maven shader插件构建的"uberjar"可以解释为_"请忽略我应用于依赖项的所有范围并将它们打包到单个jar文件中-在您为我完成这些操作时,请为它们创建一个正确的清单文件"_ - 因此,我认为只要您创建一个合法的包含classpath定义的清单文件 - 包括驱动程序jar在内的交付jar即可正常工作 ;) - JBA

4

由于您正在通过“java -jar”运行项目并且有依赖项,因此您需要使用两个maven插件。第一个插件用于在打包时将依赖项复制到目标文件夹内的文件夹中(例如lib /),第二个插件用于指定类路径,应与第一个插件(lib /)相同。我遇到了同样的问题,以下是我的解决方法:

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-dependency-plugin</artifactId>
            <executions>
                <execution>
                    <id>copy</id>
                    <phase>package</phase>
                    <goals>
                        <goal>copy-dependencies</goal>
                    </goals>
                    <configuration>
                        <outputDirectory>
                            ${project.build.directory}/lib
                        </outputDirectory>
                    </configuration>
                </execution>
            </executions>
        </plugin>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-jar-plugin</artifactId>
            <configuration>
                <archive>
                    <manifest>
                        <addClasspath>true</addClasspath>
                        <classpathPrefix>lib/</classpathPrefix>

                  <mainClass>com.tihoo.crawler.Application</mainClass>
                    </manifest>
                </archive>
            </configuration>
        </plugin>
    </plugins>
</build>

3
答案在这里 - 如何使用Maven创建带有依赖关系的可执行JAR文件? 我需要构建一个超级POM,使用上面链接中的答案 - 这将依赖项(在本例中是mysql jar文件)构建到单个SNAPSHOT JAR文件中。
只需确保使用mvn clean compile assembly:single运行它(而不是通常的mvn clean package或其他命令)。

1
着色器插件绑定到“package”阶段,并在运行“mvn clean package”时执行;)再次查看如何为可执行的jar创建清单 - 我期望这是您实际遇到的问题 - 与Maven无关;) - JBA
谢谢,我会去查看Shader的。 - pokero
我遇到了同样的问题,只需要记住 assembly:single 这一点就可以了 :) - Svend Hansen

0

我也遇到了这个问题。我尝试使用插件将连接器设置为类路径,但没有成功。我尝试更改版本,但也没有成功。我花了两个晚上才发现我需要在pom.xml中指定我的包需要是“war”类型。

也许是因为你的项目不知道它是什么类型,所以尝试加入这个:

<packaging>war</packaging>

就在您的项目版本旁边。类似于这样:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>com.example</groupId>
<artifactId>example-app</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging> <!-- Here -->

<properties>
    <!-- Some properties here -->
</properties>

<dependencies>
    <!-- Some dependencies here -->
</dependencies>

也许它不适合你的问题,但也许其他人会需要它。


-3

添加这段代码

    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.6</version>
    </dependency>

将此代码添加到您的Maven项目的pom.xml文件中。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接