Maven构建含依赖Jar遇类找不到及主清单属性缺失问题
一、maven-assembly-plugin打包后缺失本地system依赖的问题
你遇到的NoClassDefFoundError核心原因是maven-assembly-plugin默认不会包含scope=system的依赖——哪怕你在dependency节点里声明了这个本地Jar,打包插件也会直接忽略它,所以解压主Jar后找不到jave相关的类文件。
可行解决办法:
按推荐程度排序,给你几个方案:
将本地Jar安装到本地Maven仓库(最推荐,避免system scope的各种坑)
执行这条命令把Jar安装到本地仓库,之后就能像普通依赖一样引用,不用再依赖system scope:mvn install:install-file -Dfile=${project.basedir}/src/main/resources/jave-1.0.2.jar -DgroupId=it.sauronsoftware.jave -DartifactId=jave -Dversion=1.0 -Dpackaging=jar安装完成后,把dependency里的
<scope>system</scope>和<systemPath>删掉,保留正常的groupId、artifactId、version即可。修改assembly插件配置,强制包含system依赖
在maven-assembly-plugin的configuration里添加<includeScope>system</includeScope>,让插件打包时纳入system scope的依赖:<plugin> <artifactId>maven-assembly-plugin</artifactId> <configuration> <archive> <manifest> <mainClass>com.rilent.App</mainClass> </manifest> </archive> <descriptorRefs> <descriptorRef>jar-with-dependencies</descriptorRef> </descriptorRefs> <!-- 添加这一行,强制包含system依赖 --> <includeScope>system</includeScope> </configuration> <!-- 建议绑定到package阶段,执行mvn package就能自动打包 --> <executions> <execution> <phase>package</phase> <goals> <goal>single</goal> </goals> </execution> </executions> </plugin>
二、onejar-maven-plugin配置错误导致"no main manifest attribute"的问题
你这里犯了一个典型错误:把onejar-maven-plugin当成普通dependency引入了,它本质是Maven插件,应该放在<build><plugins>节点下,而不是<dependencies>里。而且你没有配置主类和执行目标,导致打包出来的Jar没有主清单属性。
正确配置方式:
把它从<dependencies>移除,放到<build><plugins>中,同时配置主类和绑定打包阶段:
<build> <plugins> <!-- onejar-maven-plugin 正确配置 --> <plugin> <groupId>com.jolira</groupId> <artifactId>onejar-maven-plugin</artifactId> <version>1.4.4</version> <executions> <execution> <goals> <goal>one-jar</goal> </goals> </execution> </executions> <configuration> <mainClass>com.rilent.App</mainClass> <!-- 你提到的exe文件只要放在src/main/resources下,插件会自动打包进去 --> </configuration> </plugin> </plugins> </build>
然后执行打包命令:
mvn clean package
打包完成后,会生成一个类似myapp-0.0.1-SNAPSHOT.one-jar.jar的文件,运行这个Jar就不会出现主清单属性缺失的问题了。
另外补充:你Jar中要包含的.exe文件,只要放在src/main/resources目录下,不管用assembly还是onejar插件,都会被打包到Jar的resources目录中,运行时可以通过类路径访问到它。
内容的提问来源于stack exchange,提问作者rilent

