
maven项目默认生成的jar不包含依赖和主类声明,导致无法直接双击运行;需通过maven-jar-plugin配置manifest,并用maven-assembly-plugin构建含所有依赖的fat jar。
maven项目默认生成的jar不包含依赖和主类声明,导致无法直接双击运行;需通过maven-jar-plugin配置manifest,并用maven-assembly-plugin构建含所有依赖的fat jar。
在NetBeans中将Java Swing/FX项目从Ant迁移到Maven后,常遇到一个典型问题:编译成功、IDE内可正常运行(mvn javafx:run),但导出的.jar文件双击无响应、命令行执行报no main manifest attribute或ClassNotFoundException——这并非代码或Java环境故障,而是Maven默认打包机制与可执行JAR规范存在根本差异。
? 问题根源:Maven默认JAR ≠ 可执行JAR
- Ant项目(如NetBeans旧模板)默认使用nbproject/project.properties配置main.class,并由IDE自动注入MANIFEST.MF中的Main-Class及Class-Path;
- Maven的mvn package仅生成仅含自身编译字节码的JAR(即“thin JAR”),不包含任何依赖库(如Apache POI、JavaFX模块),也不写入可执行所需的MANIFEST属性;
- 即使你已正确声明
于javafx-maven-plugin,该插件仅影响javafx:run生命周期,对最终生成的JAR文件无任何影响。
✅ 正确解决方案:双插件协同构建fat JAR
你需要两个Maven插件协同工作:
- maven-jar-plugin:向JAR的META-INF/MANIFEST.MF写入Main-Class(必需)和Class-Path(可选);
- maven-assembly-plugin:将项目字节码 + 所有依赖JAR合并为单个“fat JAR”(又称uber JAR),确保运行时类路径完整。
以下是精简、可靠、经验证的pom.xml关键配置(已移除冗余插件和错误依赖):
<build>
<plugins>
<!-- Step 1: 配置可执行MANIFEST -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.3.0</version> <!-- 推荐使用较新版本 -->
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<mainClass>com.groupself.productpricelister.GroceryProductsLister</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
<!-- Step 2: 构建含全部依赖的fat JAR -->
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.6.0</version>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<archive>
<manifest>
<mainClass>com.groupself.productpricelister.GroceryProductsLister</mainClass>
</manifest>
</archive>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>✅ 构建命令:在项目根目录执行
立即学习“Java免费学习笔记(深入)”;
mvn clean package成功后,目标目录下将生成两个JAR:
- ProductPricesLister-1.0.jar(thin JAR,仅含本项目class,不可执行)
- ProductPricesLister-1.0-jar-with-dependencies.jar(fat JAR,这才是你要双击或java -jar运行的文件)
⚠️ 关键注意事项
-
依赖版本一致性:原POM中poi与poi-ooxml版本不一致(5.0.0 vs 5.2.3),且错误添加了
pom.sha512 (应为jar)。务必统一使用相同版本(推荐5.2.4或5.3.0,兼容Java 11+):<dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>5.2.4</version> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</artifactId> <version>5.2.4</version> </dependency> JavaFX模块需显式处理:若使用JavaFX 11+(非JDK内置),javafx-controls等依赖需通过--module-path和--add-modules启动。maven-assembly-plugin无法自动处理模块路径。推荐方案:
✅ 使用jlink构建自包含运行时镜像(生产首选);
⚠️ 或改用maven-shade-plugin(支持Transformers配置JavaFX模块反射);
❌ 避免在fat JAR中混入JavaFX类(易引发UnsupportedOperationException: Cannot load class)。-
调试技巧:当JAR双击无反应时,切勿仅依赖GUI反馈。请在终端执行:
java -jar target/ProductPricesLister-1.0-jar-with-dependencies.jar
实时查看异常堆栈(如NoClassDefFoundError、IllegalAccessError),这是定位依赖缺失或模块冲突的唯一可靠方式。
✅ 总结
Maven项目生成可执行JAR不是“开箱即用”,而是需主动声明打包契约。核心就两点:
① 用maven-jar-plugin注入Main-Class到MANIFEST;
② 用maven-assembly-plugin(或maven-shade-plugin)合并依赖生成fat JAR。
完成这两步,你的Excel数据管理工具就能像旧版TXT程序一样,双击即启、稳定运行——技术升级不该牺牲用户体验,而应通过正确的工程实践无缝承接。








