如何为基于JDK11的Maven JavaFX项目打包可运行Jar
解决方案
1. 添加自定义启动代理类
创建一个普通Java类作为启动入口,避免直接调用JavaFX的Application类(模块化环境下的限制):
package hu.infokristaly.jpasswordprotector; public class Launcher { public static void main(String[] args) { JPasswordProtector.main(args); } }
2. 修改pom.xml配置
替换原build/plugins节点内容,添加maven-shade-plugin打包所有依赖(包括JavaFX库),同时保留开发用的javafx-maven-plugin:
<build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.10.1</version> <configuration> <release>11</release> </configuration> </plugin> <!-- 开发运行用的JavaFX插件 --> <plugin> <groupId>org.openjfx</groupId> <artifactId>javafx-maven-plugin</artifactId> <version>0.0.8</version> <configuration> <mainClass>hu.infokristaly.jpasswordprotector.JPasswordProtector</mainClass> <options> <option>--add-exports</option> <option>javafx.base/com.sun.javafx.event=org.controlsfx.controls</option> </options> </configuration> <executions> <execution> <id>default-cli</id> </execution> <execution> <id>debug</id> <configuration> <options> <option>-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=localhost:8000</option> </options> </configuration> </execution> <execution> <id>ide-debug</id> <configuration> <options> <option>-agentlib:jdwp=transport=dt_socket,server=n,address=${jpda.address}</option> <option>--add-exports</option> <option>javafx.base/com.sun.javafx.event=org.controlsfx.controls</option> </options> </configuration> </execution> <execution> <id>ide-profile</id> <configuration> <options> <option>${profiler.jvmargs.arg1}</option> <option>${profiler.jvmargs.arg2}</option> <option>${profiler.jvmargs.arg3}</option> <option>${profiler.jvmargs.arg4}</option> <option>${profiler.jvmargs.arg5}</option> </options> </configuration> </execution> </executions> </plugin> <!-- 打包可运行Jar用的Shade插件 --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <version>3.4.1</version> <executions> <execution> <phase>package</phase> <goals> <goal>shade</goal> </goals> <configuration> <createDependencyReducedPom>false</createDependencyReducedPom> <shadedArtifactAttached>true</shadedArtifactAttached> <shadedClassifierName>jar-with-dependencies</shadedClassifierName> <transformers> <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"> <mainClass>hu.infokristaly.jpasswordprotector.Launcher</mainClass> </transformer> <transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/> </transformers> <filters> <filter> <artifact>*:*</artifact> <excludes> <exclude>META-INF/*.SF</exclude> <exclude>META-INF/*.DSA</exclude> <exclude>META-INF/*.RSA</exclude> </excludes> </filter> </filters> </configuration> </execution> </executions> </plugin> </plugins> </build>
3. 打包与运行
- 执行打包命令:
mvn clean package - 在
target目录找到生成的JPasswordProtectorJDK11-1.0-SNAPSHOT-jar-with-dependencies.jar,重命名为JPasswordProtector.jar - 运行时必须携带ControlsFX所需的JVM参数:
java --add-exports javafx.base/com.sun.javafx.event=org.controlsfx.controls -jar JPasswordProtector.jar
简化运行方式(可选)
如果不想每次输入参数,可创建启动脚本:
Windows(start.bat)
@echo off java --add-exports javafx.base/com.sun.javafx.event=org.controlsfx.controls -jar JPasswordProtector.jar
Linux/macOS(start.sh)
#!/bin/bash java --add-exports javafx.base/com.sun.javafx.event=org.controlsfx.controls -jar JPasswordProtector.jar
内容的提问来源于stack exchange,提问作者Papp Zoltán
相关产品推荐
相关产品推荐

