如果我还不知道如何运行maven生成的可执行jar,我就会对此感到困惑并感到羞耻。
myapp-uberjar.jar包含以下内容:
com/myapp/... (all my project packages and classes are here) META-INF/MANIFEST.MF dependency1.jar dependency2.jar ...
清单似乎还可以(为简洁起见,我在这里删除了一些依赖项):
Manifest-Version: 1.0 Archiver-Version: Plexus Archiver Created-By: Apache Maven Built-By: rabdi Build-Jdk: 1.6.0_18 Main-Class: com.myapp.core.main.Boot Class-Path: spring-context-3.0.5.RELEASE.jar spring-context-support-3.0.5.RELEASE.jar spring-test-3.0.5.RELEASE.jar axis-1.4.jar axis-jaxrpc-1.4.jar axis -saaj-1.4.jar axis-wsdl4j-1.5.1.jar commons-discovery-0.2.jar xml-api s-1.0.b2.jar log4j-1.2.15.jar commons-pool-1.5.4.jar hamcrest-core-1.1.jar junit-de p-4.8.2.jar
现在,当我去运行我的罐子时,我遇到以下错误:
D:\myapp\target>java -jar myapp-uberjar.jar Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/log4j/Logger at com.myapp.core.main.Boot.(Boot.java:14) Caused by: java.lang.ClassNotFoundException: org.apache.log4j.Logger at java.net.URLClassLoader$1.run(Unknown Source) at java.security.AccessController.doPrivileged(Native Method) at java.net.URLClassLoader.findClass(Unknown Source) at java.lang.ClassLoader.loadClass(Unknown Source) at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source) at java.lang.ClassLoader.loadClass(Unknown Source) ... 1 more Could not find the main class: com.myapp.core.main.Boot. Program will exit.
为什么它不起作用?如何让它发挥作用。
谢谢!
答案 0 :(得分:2)
如果您的distribute my program as single zip with my jar and libraries
,那么您必须构建一个类路径。
如果你想让依赖关系将jar放到jar的外面(强烈推荐),你将不得不使用汇编插件(或其他插件来实现)。
这里有一个完整的解释如何做到这一点:
pom构建元素:
<build>
<!-- final name set the jar name, if left it
will give defualt "${artifactId}-${version}" -->
<finalName>jar final name</finalName>
<sourceDirectory>src</sourceDirectory>
<!-- compiler plug in -->
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
<!-- assembly plugin -->
<!-- the assembly plugin is used to define your
final deploy output (jar, zip, dir, war, etc..)-->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<id>assembly:package</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<!-- The filename of the assembled distribution
file defualt ${project.build.finalName}-->
<finalName>${project.build.finalName}</finalName>
<appendAssemblyId>false</appendAssemblyId>
<!-- A list of descriptor files path to generate from-->
<descriptors>
<descriptor>assembly/assembly.xml</descriptor>
</descriptors>
</configuration>
</execution>
</executions>
</plugin>
<!-- jar plug in -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.3</version>
<configuration>
<archive>
<manifest>
<mainClass>fully.qualified.MainClass</mainClass>
<!-- to create a class path to your
dependecies you have to fill true in this field-->
<addClasspath>true</addClasspath>
<!-- if you put your dependencySet/outputDirectory
in the assembly file is in a specific folder (lib for example),
you need to add classpathPrefix-->
<classpathPrefix>lib/</classpathPrefix>
<!-- if you defined your dependencySet/outputFileNameMapping
in the assembly, instead of using the classpathPrefix,
you should use customClasspathLayout,
add the classpathPrefix at the begining of the
customClasspathLayout, and then add the pattern of the outputFileNameMapping,
NOTICE YOU NEED TO ADD '$' BEFOR OF EACH '$'.
supported only from version 2.3>-->
<!--<classpathLayoutType>custom</classpathLayoutType>
<customClasspathLayout>
lib/$${artifact.groupId}.$${artifact.artifactId}.$${artifact.extension}
</customClasspathLayout>-->
</manifest>
<manifestEntries>
<Class-Path>conf/</Class-Path>
</manifestEntries>
</archive>
</configuration>
</plugin>
</plugins>
</build>
汇编文件:
<?xml version="1.0" encoding="UTF-8"?>
<assembly>
<!--the id will be add to the end of the distribution file -->
<id>package</id>
<formats>
<format>zip</format>
</formats>
<includeBaseDirectory>true</includeBaseDirectory>
<fileSets>
<fileSet>
<directory>target</directory>
<outputDirectory></outputDirectory>
<includes>
<include>*.jar</include>
</includes>
</fileSet>
<fileSet>
<directory>icons</directory>
<outputDirectory>icons</outputDirectory>
<includes>
<include>**/*</include>
</includes>
</fileSet>
<fileSet>
<directory>conf</directory>
<outputDirectory>conf</outputDirectory>
<includes>
<include>**/*</include>
</includes>
</fileSet>
</fileSets>
<files>
<!-- you need to create the bat file yourself -->
<file>
<source>batFileName.bat</source>
<filtered>true</filtered>
</file>
</files>
<dependencySets>
<dependencySet>
<!--define the outputDirectory of the dependencies,
NOTICE: if it's diffrent from '/' make sure to
change the classPath configuration for
the maven-jar-plugin in the pom-->
<outputDirectory>lib</outputDirectory>
<!-- maping the dependencies jar names.
NOTICE : if you used this definition, you need to use
customClasspathLayout classPath configuration
for the maven-jar-plugin in the pomg-->
<outputFileNameMapping>
${artifact.groupId}.${artifact.artifactId}.${artifact.extension}
</outputFileNameMapping>
<unpack>false</unpack>
</dependencySet>
</dependencySets>
</assembly>
答案 1 :(得分:1)
第一种可能性:Java期望类路径上的所有jar都与可执行jar位于同一目录中。是吗?