【问题标题】:Maven not setting classpath for dependencies properlyMaven 没有为依赖项正确设置类路径
【发布时间】:2011-06-08 22:13:34
【问题描述】:

操作系统名称:“linux”版本:“2.6.32-27-generic”arch:“i386”系列:“unix”

Apache Maven 2.2.1 (r801777; 2009-08-06 12:16:01-0700)

Java 版本:1.6.0_20

我正在尝试在 ubuntu 中将 mysql 依赖项与 maven 一起使用。如果我将 maven 下载的“mysql-connector-java-5.1.14.jar”文件移动到我的 $JAVA_HOME/jre/lib/ext/ 文件夹中,当我运行 jar 时一切都很好。

我认为我应该能够只在 pom.xml 文件中指定依赖项,并且 maven 应该负责自动设置依赖项 jar 的类路径。这是不正确的吗?

我的 pom.xml 文件如下所示:

<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.ion.common</groupId>
  <artifactId>TestPreparation</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>jar</packaging>

  <name>TestPrep</name>
  <url>http://maven.apache.org</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>

  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-jar-plugin</artifactId>

        <configuration>
          <archive>
            <manifest>
              <addClasspath>true</addClasspath>
              <mainClass>com.ion.common.App</mainClass>
            </manifest>
          </archive>
        </configuration>

      </plugin>
    </plugins>
  </build>

  <dependencies>

    <!-- JUnit testing dependency -->
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>

    <!-- MySQL database driver -->
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>5.1.14</version>
      <scope>compile</scope>
    </dependency>

  </dependencies>
</project>

命令“mvn package”构建没有任何问题,我可以运行它,但是当应用程序尝试访问数据库时,就会出现这个错误:

java.lang.ClassNotFoundException: com.mysql.jdbc.Driver
        at java.net.URLClassLoader$1.run(URLClassLoader.java:217)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(URLClassLoader.java:205)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:321)
        at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:294)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:266)
        at java.lang.Class.forName0(Native Method)
        at java.lang.Class.forName(Class.java:186)
        at com.ion.common.Functions.databases(Functions.java:107)
        at com.ion.common.App.main(App.java:31)

失败的那一行是:

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

谁能告诉我我做错了什么或如何解决它?

【问题讨论】:

    标签: dependencies maven classpath


    【解决方案1】:

    或者,如果您使用的是maven-shade-plugin,解决方法是添加一个过滤器以包含丢失的文件:

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-shade-plugin</artifactId>
                <version>3.1.0</version>
                <executions>
                    <execution>
                        ...
                        <configuration>
                            ...
                            <filters>
                                ...                                
                                <filter>
                                    <artifact>com.sun.istack</artifact>
                                    <includes>
                                        <include>**</include>
                                    </includes>
                                </filter>
    

    【讨论】:

      【解决方案2】:

      我知道这个问题很老,但它显示在搜索的顶部,让 Maven 使用 -SNAPSHOT 版本正确设置依赖项,我必须改进接受的解决方案以使我的类路径解析正常工作。

      我遇到的问题是 maven-jar-plugin 包含一个依赖项的 resolvedVersion(例如 --.jar),而 maven-dependency-plugin(从 2.5.1 版开始)复制依赖项并保留其 baseVersion - -SNAPSHOT.jar)。 (有关该增强功能的更多信息,请参阅https://jira.codehaus.org/browse/MDEP-380。)

      为了让事情正常进行,我必须按如下方式关闭此行为:

          ...
          <plugins>
              <plugin>
                  <groupId>org.apache.maven.plugins</groupId>
                  <artifactId>maven-jar-plugin</artifactId>
                  <configuration>
                      <archive>
                          <manifest>
                              <addClasspath>true</addClasspath>
                              <classpathPrefix>dependency/</classpathPrefix>
                              <mainClass>com.example.MainClass</mainClass>
                          </manifest>
                      </archive>
                  </configuration>
              </plugin>
      
              <plugin>
                  <groupId>org.apache.maven.plugins</groupId>
                  <artifactId>maven-dependency-plugin</artifactId>
                  <executions>
                      <execution>
                          <id>copy-dependencies</id>
                          <phase>package</phase>
                          <goals>
                              <goal>copy-dependencies</goal>
                          </goals>
                          <configuration>
                              <useBaseVersion>false</useBaseVersion>
                          </configuration>
                      </execution>
                  </executions>
              </plugin>
          </plugins>
          ...
      

      此配置导致依赖项被复制到 ${project.build.directory}/dependency 中,其 resolvedVersion 与 maven-jar-plugin 设置到 META-INF/MANIFEST.MF 中的 blasspath 匹配。希望这对将来的某人有所帮助。

      【讨论】:

      • 根据 bug tracker,这个问题从 2.6 版开始修复。
      【解决方案3】:

      Raghuram 推动了我朝着正确的方向前进。让 maven 负责自动复制 jar 的方法是将此代码添加到 pom.xml 文件中的标记内:

        <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-dependency-plugin</artifactId>
          <executions>
            <execution>
              <id>copy-dependencies</id>
              <phase>package</phase>
              <goals>
                <goal>copy-dependencies</goal>
              </goals>
              <configuration>
                <outputDirectory>${project.build.directory}</outputDirectory>
                <overWriteReleases>false</overWriteReleases>
                <overWriteSnapshots>true</overWriteSnapshots>
              </configuration>
            </execution>
          </executions>
        </plugin>
      

      可以在此处找到有关此内容的更多详细信息: https://maven.apache.org/plugins/maven-dependency-plugin/usage.html

      让 maven 将 jar 打包在一起会很好,但这足以回答这个问题。关于stackoverflow的相关答案:

      Building executable jar with maven?

      How can I create an executable JAR with dependencies using Maven?

      【讨论】:

      • +1 用于链接到 maven-assembly-plugin。这是另一个:maven.apache.org/plugins/maven-assembly-plugin/usage.html
      • 将部门复制到哪里?我认为它会将它们放在您的项目中的某个地方?将它们从 ~/.m2 复制到您的本地项目,但是在您的本地项目中的哪个位置?
      • @AlexanderMills 配置通过outputDirectory 声明目的地。同样常见的是${project.build.directory}/lib, which adds all jars into a lib`目录。
      【解决方案4】:

      Maven 确实将类路径设置为正确的依赖项,但没有以存储库位置为前缀。在您的 Manifest 文件中将如下所示。

      Class-Path: mysql-connector-java-5.1.14.jar
      

      您可以将依赖的 jar 放在与您正在运行的 jar 相同的文件夹中。

      参考the examples

      【讨论】:

      • 谢谢,这让我更接近了。我能够将 dependency:copy-dependencies 目标添加到 pom.xml 文件中,以让 maven 自动处理复制依赖项。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-03-03
      • 2021-11-06
      • 1970-01-01
      • 2012-11-11
      • 2013-01-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多