2016-02-17 52 views
0

我创建了一个可执行的JAR从行家与下面的生成配置:运行在命令行可执行的JAR失败,因为缺少库

<plugins> 
    <plugin> 
    <groupId>org.apache.maven.plugins</groupId> 
    <artifactId>maven-compiler-plugin</artifactId> 
    <version>3.2</version> 
    <configuration> 
     <source>1.8</source> 
     <target>1.8</target> 
    </configuration> 
    </plugin> 
    <plugin> 
    <groupId>org.apache.maven.plugins</groupId> 
    <artifactId>maven-dependency-plugin</artifactId> 
    <executions> 
     <execution> 
      <id>copy-dependencies</id> 
      <phase>prepare-package</phase> 
      <goals> 
       <goal>copy-dependencies</goal> 
      </goals> 
      <configuration> 
       <outputDirectory>${project.build.directory}/${project.build.targetName}/lib</outputDirectory> 
       <overWriteReleases>false</overWriteReleases> 
       <overWriteSnapshots>false</overWriteSnapshots> 
       <overWriteIfNewer>true</overWriteIfNewer> 
       <excludeScope>test</excludeScope> 
       <includeScope>compile</includeScope> 
      </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> 
       <packageName>${project.build.packageName}</packageName> 
       <mainClass>${project.build.packageName}.${project.build.className}</mainClass> 
      </manifest> 
      <manifestEntries> 
       <Class-Path>.</Class-Path> 
      </manifestEntries> 
     </archive> 
     <finalName>${project.build.targetName}/${project.build.targetName}</finalName> 
    </configuration> 
    </plugin> 

即生成以下文件:

./lib/axis-2878297.jar 
./lib/axis-wsdl4j-1.5.1.jar 
./lib/(other dependencies jars) 
./target.jar 

1.如果我以这种方式从命令行运行这个jar:

java -jar target.jar 

它会产生异常:

Exception in thread "main" java.lang.NoClassDefFoundError: javax/wsdl/OperationType 
     at org.apache.axis.description.OperationDesc.<clinit>(OperationDesc.java:59) 
     ... 

2,如果我在其他的方式运行:

java -cp "target.jar;lib\*" com.test.Main 

的执行一定会成功。

P.S.我试图把-verbose:class放到命令中。

对于案例1它表明:

[Loaded org.apache.axis.description.OperationDesc from file:/C:/build/lib/axis-2878297.jar] 
[Loaded java.lang.Throwable$PrintStreamOrWriter from C:\Program Files\Java\jre1.8.0_74\lib\rt.jar] 
[...] 

虽然情况二所示:

[Loaded org.apache.axis.description.OperationDesc from file:/C:/build/lib/axis-2878297.jar] 
[Loaded javax.wsdl.OperationType from file:/C:/build/lib/axis-wsdl4j-1.5.1.jar] 
[...] 

是什么原因,这种情况下,1失败?

谢谢。

+0

查看target.jar中的MANIFEST.MF文件。 Class-Path行应明确提及所有lib/*文件,并从target.jar开始提供正确的相对路径名。 –

+0

@ThorbjørnRavnAndersen谢谢你的提示。有趣的是,在MANIFEST.MF中,除了axis-wsdl4j-1.5.1.jar之外,lib下的所有jar都包含在Class-Path中。 – Lee

回答

1

我能够使用Maven shade plugin来完成这项工作。

我使用了Mykong的教程。

演示应用程序是使用乔达时间命令行应用程序:

package com.mykong.core.utils; 

import org.apache.log4j.Logger; 
import org.joda.time.LocalDate; 

/** 
* Hello world! 
* @link http://www.mkyong.com/maven/how-to-create-a-jar-file-with-maven/ 
*/ 
public class App { 
    public static final Logger LOGGER = Logger.getLogger(App.class); 

    public static void main(String[] args) { 
     System.out.println(getLocalCurrentDate()); 
    } 

    private static String getLocalCurrentDate() { 
     String result = ""; 
     try { 
      if (LOGGER.isDebugEnabled()) { 
       LOGGER.debug("enter getLocalCurrentDate"); 
      } 
      result = new LocalDate().toString(); 
     } finally { 
      if (LOGGER.isDebugEnabled()) { 
       LOGGER.debug("exit getLocalCurrentDate"); 
      } 
     } 
     return result; 
    } 
} 

这里是我的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/maven-v4_0_0.xsd"> 
    <modelVersion>4.0.0</modelVersion> 
    <groupId>com.mykong.core.utils</groupId> 
    <artifactId>dateUtils</artifactId> 

    <packaging>jar</packaging> 

    <version>1.0-SNAPSHOT</version> 
    <name>dateUtils</name> 
    <url>http://maven.apache.org</url> 

    <properties> 
    <jdk.version>1.8</jdk.version> 
    </properties> 

    <dependencies> 
    <dependency> 
     <groupId>joda-time</groupId> 
     <artifactId>joda-time</artifactId> 
     <version>2.9.1</version> 
    </dependency> 
    <dependency> 
     <groupId>junit</groupId> 
     <artifactId>junit</artifactId> 
     <version>4.12</version> 
     <scope>test</scope> 
    </dependency> 
    <dependency> 
     <groupId>log4j</groupId> 
     <artifactId>log4j</artifactId> 
     <version>1.2.17</version> 
    </dependency> 
    </dependencies> 

    <build> 
    <finalName>dateutils</finalName> 
    <plugins> 
     <plugin> 
      <groupId>org.apache.maven.plugins</groupId> 
      <artifactId>maven-shade-plugin</artifactId> 
      <version>2.4.3</version> 
      <executions> 
       <execution> 
        <phase>package</phase> 
        <goals> 
         <goal>shade</goal> 
        </goals> 
       </execution> 
      </executions> 
      <configuration> 
       <transformers> 
        <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"> 
         <manifestEntries> 
          <Main-Class>com.mykong.core.utils.App</Main-Class> 
          <Build-Number>1</Build-Number> 
         </manifestEntries> 
        </transformer> 
       </transformers> 
      </configuration> 
     </plugin> 
    </plugins> 
    </build> 

    <pluginRepositories> 
     <pluginRepository> 
      <id>central</id> 
      <url>http://repo1.maven.org/maven2/</url> 
     </pluginRepository> 
    </pluginRepositories> 
</project> 
1

行我的原因:

在pom.xml中我设置轴WSDL4J的范围,以“提供”,表示我期望JDK或容器,以提供在运行时的依赖性。所以当maven编写manifest.mf时,它会跳过这种依赖关系。

感谢您的所有答案和帮助。

<dependency> 
    <groupId>axis</groupId> 
    <artifactId>axis-wsdl4j</artifactId> 
    <version>1.5.1</version> 
    <scope>provided</scope> 
</dependency>