有一个基于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>
答案 0 :(得分:5)
使用java -jar
运行Jar时,您不再使用maven解析依赖项运行。您必须确保您所依赖的所有罐子都在Jar中MANIFEST.mf
文件中指定的相对容量中可用。通常,您将使用程序集插件创建可创建此结构的可分发存档。或者您可以使用uberjar / onejar插件将所有内容都包含在Jar中。
答案 1 :(得分: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>
答案 2 :(得分:0)
我也看到了这个问题。 Cobertura通过字节码操作创建所有已编译类文件(在目标/类中)的检测副本。我的jar文件包含已检测的类文件(来自target / generated-classes / cobertura),但缺少cobertura.jar。所以,ClassNotFoundException是正确的反应。
但是,由于我的POM不包含任何提示,这是打包的目标类,Maven可以自由选择......它使用已检测的文件集。
我的解决方案非常简单:mvn clean和mvn包。第一个调用将删除所有已检测的类。然后,第二个调用只找到未经过测试的类,而没有任何外部引用Cobertura。