7

有一个基于 maven 的项目,可以通过 构建maven install,但是在运行 out jar 时会抛出异常:

Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/commons/cli/CommandLineParser
Caused by: java.lang.ClassNotFoundException: org.apache.commons.cli.CommandLineParser
    at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:247)

我想知道为什么java找不到maven依赖库?

<?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/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>org.artofsolving.jodconverter</groupId>
  <artifactId>jodconverter-core</artifactId>
  <version>3.0-SNAPSHOT</version>
  <packaging>jar</packaging>

  <name>JODConverter - Core Library</name>
  <description>
    JODConverter converts office documents using OpenOffice.org
  </description>
  <url>http://jodconverter.googlecode.com</url>
  <licenses>
    <license>
      <name>GNU Lesser General Public License, Version 3 or later</name>
      <url>http://www.gnu.org/licenses/lgpl.html</url>
    </license>
  </licenses>
  <scm>
    <url>http://jodconverter.googlecode.com/svn/trunk/jodconverter-core</url>
    <connection>scm:svn:https://jodconverter.googlecode.com/svn/trunk/jodconverter-core/</connection>
  </scm>
  <inceptionYear>2003</inceptionYear>
  <developers>
    <developer>
      <id>mirko.nasato</id>
      <name>Mirko Nasato</name>
      <email>mirko@artofsolving.com</email>
    </developer>
  </developers>
  <contributors>
    <contributor>
      <name>Shervin Asgari</name>
      <email>shervin@asgari.no</email>
    </contributor>
  </contributors>

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

  <repositories>
    <repository>
      <!-- required for org.hyperic:sigar -->
      <id>jboss-public-repository-group</id>
      <url>https://repository.jboss.org/nexus/content/groups/public-jboss/</url>
    </repository>
  </repositories>

  <dependencies>

    <!-- Required dependencies -->

    <dependency>
      <groupId>commons-io</groupId>
      <artifactId>commons-io</artifactId>
      <version>1.4</version>
    </dependency>
    <dependency>
      <groupId>org.openoffice</groupId>
      <artifactId>juh</artifactId>
      <version>3.2.1</version>
    </dependency>
    <dependency>
      <groupId>org.openoffice</groupId>
      <artifactId>ridl</artifactId>
      <version>3.2.1</version>
    </dependency>
    <dependency>
      <groupId>org.openoffice</groupId>
      <artifactId>unoil</artifactId>
      <version>3.2.1</version>
    </dependency>

    <dependency>
      <!-- for the command line tool -->
      <groupId>commons-cli</groupId>
      <artifactId>commons-cli</artifactId>
      <version>1.2</version>
    </dependency>

    <!-- Optional dependencies -->


    <dependency>
      <!-- for more robust process management -->
      <groupId>org.hyperic</groupId>
      <artifactId>sigar</artifactId>
      <version>1.6.5.132</version>
      <optional>true</optional>
    </dependency>
    <dependency>
      <!-- for JSON configuration -->
      <groupId>org.json</groupId>
      <artifactId>json</artifactId>
      <version>20090211</version>
      <optional>true</optional>
    </dependency>

    <!--  Test dependencies -->

    <dependency>
      <groupId>org.testng</groupId>
      <artifactId>testng</artifactId>
      <version>6.0.1</version>
      <scope>test</scope>
    </dependency>

  </dependencies>

  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>2.3.2</version>
        <configuration>
          <source>1.6</source>
          <target>1.6</target>
          <encoding>UTF-8</encoding>
        </configuration>
      </plugin>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-surefire-plugin</artifactId>
        <version>2.7.2</version>
        <configuration>
          <!-- don't run tests in parallel -->
          <perCoreThreadCount>false</perCoreThreadCount>
          <threadCount>1</threadCount>
        </configuration>
      </plugin>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-jar-plugin</artifactId>
        <version>2.3.1</version>
        <configuration>
          <archive>
            <manifest>
              <mainClass>org.artofsolving.jodconverter.cli.Convert</mainClass>
              <addClasspath>true</addClasspath>
            </manifest>
          </archive>
        </configuration>
      </plugin>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-assembly-plugin</artifactId>
        <version>2.2-beta-5</version>
        <configuration>
          <descriptors>
            <descriptor>src/main/assembly/dist.xml</descriptor>
          </descriptors>
        </configuration>
      </plugin>
    </plugins>
  </build>

  <reporting>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-javadoc-plugin</artifactId>
        <version>2.7</version>
      </plugin>
      <plugin>
        <groupId>org.codehaus.mojo</groupId>
        <artifactId>cobertura-maven-plugin</artifactId>
        <version>2.4</version>
      </plugin>
    </plugins>
  </reporting>

</project>
4

3 回答 3

5

使用 运行 Jar 时java -jar,您不再使用 maven 解析依赖项运行。您必须确保您所依赖的所有 jar 在您的 Jar.jarMANIFEST.mf文件中指定的相对位置可用。通常,您会使用程序集插件来创建一个可分发的存档来创建此结构。或者您可以使用 uberjar/onejar 插件将所有内容包含在您的 Jar 中。

于 2013-04-08T06:40:32.733 回答
5

您有 2 个选项来解决此问题:

选项 1 - 使用下面的两个插件将依赖项复制到“lib”文件夹(请参阅 outputDirectory)并让您的 Runnable JAR 知道它们在哪里(请参阅 classpathPrefix)

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
    <archive>
        <manifest>
            <addClasspath>true</addClasspath>
            <classpathPrefix>lib/</classpathPrefix>
            <mainClass>example.MyMainClass</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>
            <outputDirectory>${project.build.directory}/lib</outputDirectory>
            <overWriteReleases>false</overWriteReleases>
            <overWriteSnapshots>false</overWriteSnapshots>
            <overWriteIfNewer>true</overWriteIfNewer>
        </configuration>
    </execution>
</executions>


选项 2 - 使用 maven-assembly-plugin 创建包含所有依赖项的单个 JAR。(所有依赖项都在同一个 JAR 中一起提取和压缩)

<assembly
xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd">

<id>with-dependencies</id>
<formats>
    <format>jar</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<dependencySets>
    <dependencySet>
        <outputDirectory>/</outputDirectory>
        <useProjectArtifact>true</useProjectArtifact>
        <unpack>true</unpack>
        <scope>compile</scope>
    </dependencySet>
</dependencySets>

于 2013-04-19T19:58:18.547 回答
0

我也看到了问题。Cobertura 通过字节码操作创建所有已编译类文件(在目标/类中)的检测副本。我的 jar 文件包含检测的类文件(来自 target/generated-classes/cobertura),但 cobertura.jar 丢失了。所以,ClassNotFoundException 是正确的反应。

但是,由于我的 POM 不包含任何提示,它们是用于打包的预期类,Maven 可以自由选择......并且它使用经过检测的文件集。

我的解决方案非常简单:mvn clean 和 mvn package。第一次调用删除所有检测类。然后,第二个调用仅查找未检测的类,而没有对 Cobertura 的任何外部引用。

于 2016-09-27T14:01:45.700 回答