Maven没有正确设置依赖关系的类路径

时间:2011-01-14 03:05:51

标签: dependencies maven classpath

操作系统名称:“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中使用maven与maven相关联。如果我将maven下载到我的$ JAVA_HOME / jre / lib / ext /文件夹中的“mysql-connector-java-5.1.14.jar”文件移动,那么当我运行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");

任何人都可以告诉我我做错了什么或如何解决它?

4 个答案:

答案 0 :(得分:19)

拉古拉姆向我推进了正确的方向。让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将罐装在一起会很好,但这足以回答这个问题。有关stackoverflow的相关答案:

Building executable jar with maven?

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

答案 1 :(得分:13)

我知道这个问题已经过时了,但它出现在搜索的顶部,让Maven正确地使用-SNAPSHOT版本设置依赖关系,我不得不改进已接受的解决方案以使我的类路径解析正常工作。

我遇到的问题是maven-jar-plugin包含了依赖的resolveVersion(例如 - .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。希望这有助于将来的某个人。

答案 2 :(得分:2)

Maven确实正确地将类路径设置为依赖项,但不以存储库位置为前缀。它将在Manifest文件中显示如下。

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

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

请参阅the examples

答案 3 :(得分:0)

或者,如果您使用的是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>