1 maven打包可执行jar条件
Maven可以使用mvn package指令对项目进行打包,如果使用Java -jar xxx.jar执行运行jar文件,会出现”no main manifest attribute, in xxx.jar”(没有设置Main-Class)、ClassNotFoundException(找不到依赖包)等错误。
要想jar包能直接通过java -jar xxx.jar运行,需要满足:
(1)在jar包中的META-INF/MANIFEST.MF中指定Main-Class。
(2)要能加载到依赖包。
2 maven-jar-plugin和maven-dependency-plugin插件打包(仅打包当前项目文件)
<plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-jar-plugin</artifactId> <version>2.6</version> <configuration> <archive> <manifest> <addClasspath>true</addClasspath> <classpathPrefix>lib/</classpathPrefix> <mainClass>com.study.MyApp</mainClass> </manifest> </archive> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-dependency-plugin</artifactId> <version>3.0.0</version> <executions> <execution> <id>copy-dependencies</id> <phase>package</phase> <goals> <goal>copy-dependencies</goal> </goals> <configuration> <outputDirectory>${project.build.directory}/lib</outputDirectory> </configuration> </execution> </executions> </plugin> </plugins>
maven-jar-plugin插件用于生成META-INF/MANIFEST.MF文件的部分内容,com.study.MyApp指定MANIFEST.MF中的Main-Class,addClasspath=true会在MANIFEST.MF加上Class-Path项并配置依赖包,lib/指定依赖包所在目录。下面是一个通过maven-jar-plugin插件生成的MANIFEST.MF文件片段:
Class-Path: lib/commons-lang3-3.8.1.jar Main-Class: com.study.MyApp
maven-dependency-plugin插件用于将依赖包拷贝到${project.build.directory}/lib目录下。
指定了Main-Class,又有了依赖包,现在我们可以运行jar包了:java -jar ./myapp.jar com.study.MyApp
3 maven-assembly-plugin插件打包(全部打到一个jar包中)
<plugin> <artifactId>maven-assembly-plugin</artifactId> <configuration> <descriptorRefs> <descriptorRef>jar-with-dependencies</descriptorRef> </descriptorRefs> <archive> <manifest> <mainClass>com.study.MyApp</mainClass> </manifest> </archive> </configuration> <executions> <execution> <id>make-assembly</id> <phase>package</phase> <goals> <goal>single</goal> </goals> </execution> </executions> </plugin>
package、single表示在执行package打包时,执行assembly:single,所以可以直接使用mvn package打包。
mvn clean package
打包后会在target目录下生成一个myapp-jar-with-dependencies.jar文件,这个文件不但包含了自己项目中的代码和资源,还包含了所有依赖包的内容(class文件)。所以可以直接通过java -jar来运行:java -jar ./myapp-jar-with-dependencies.jar com.study.MyApp
。
4 java -cp 的使用
cp是class path的简称。第2节我们使用maven-jar-plugin插件将class path添加到了MANIFEST.MF文件中,执行jar包时就不需要指定 -cp了。这次我们使用maven-jar-plugin只添加 Main-Class到清单文件,不添加Class-Path,maven-jar-plugin插件配置就不再贴出来了。
此时执行 java -jar ./myapp.jar com.study.MyApp 会报错,因为可执行jar包依赖其他jar包,解决的办法是使用 -cp替代-jar,下面以linux为例:
java -cp ./lib/*:./myapp.jar com.study.MyApp
请注意,将 ./lib/* 写成 ./lib/ 和 ./lib都会报错。
之前写的Storm文件上也有关于cp的讲解:storm -cp。