使用maven构建的jar包在命令行用java -jar
运行会提示"没有属性清单"
没有属性清单
为了让maven生成的jar包的manifest文件中加入Main-Class
,可以给maven-jar-plugin
增加如下配置
<configuration>
<archive>
<manifest>
<mainClass>yourpackagename.yourclassname</mainClass>
</manifest>
</archive>
</configuration>
再次运行程序,提示java.lang.NoClassDefFoundError
,显然是缺少依赖的第三方jar包
缺少依赖的jar包
再次查资料,似乎需要增加addClasspath
和classpathPrefix
,于是之前的配置变成了现在这样
<configuration>
<archive>
<manifest>
<mainClass>com.dizzydwarf.testaop.App</mainClass>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
</manifest>
</archive>
</configuration>
检查生成jar包中的manifest,Class-Path
中增加了依赖的jar包,并且jar包的路径被指定为lib目录。问题在于因为依赖都是通过maven下载到本地仓库,当前的classpath中不存在这些jar包,更不存在lib目录啊。
复制依赖的jar包
FatJar
在查资料的过程中,发现了FatJar这个概念,FatJar又叫UberJar,是一种可执行的jar包,因为它把依赖都打到包里面了。maven默认构建的jar包不是FatJar。
maven-dependency-plugin
这个插件可以帮我们把依赖的jar包复制到指定的目录,因此只要我们把目录指定为classpath中的目录(包括最终jar包所在目录),就能解决之前提到的问题。
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>3.1.1</version>
<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>
</plugin>
注意用eclipse自动生成的maven项目的pom.xml文件中只有pluginManagement
,没有plugins
。而这个plugin必须放在与pluginManagement
同级的plugins
下面,而不是pluginManagement
子元素的plugins
下面才有效。
更多解决方案
问题最终得到了解决,不过使用maven-dependency-plugin
的缺点在于最终生成的jar包和依赖的jar包其实还是分离的,只是我们告诉了它寻找依赖jar包的方法。当我们把最终生成的jar包复制到其他目录执行时还是会出错。想要生成真正的FatJar可以利用maven-assembly-plugin
或者maven-shade-plugin
,这里就不具体介绍了。
网友评论