如何将JavaFX应用打包为Jar文件并实现直接运行?
解决JavaFX应用生成可直接运行Jar的问题
一、先修正代码中的错误
1. 修复FrameRunApp的递归调用问题
FrameRunApp类的main方法存在无限递归调用,需改为调用JavaFX启动类的launch方法,同时修正日志配置的读取方式(打包后资源位于classpath下,不能用本地文件路径):
public class FrameRunApp { static Logger LOGGER; static { try(InputStream ins = FrameRunApp.class.getClassLoader().getResourceAsStream("log.config")) { if (ins != null) { LogManager.getLogManager().readConfiguration(ins); } LOGGER = Logger.getLogger(FrameRunApp.class.getName()); } catch (Exception e) { System.err.println("日志配置加载失败: " + e.getMessage()); LOGGER = Logger.getLogger(FrameRunApp.class.getName()); LOGGER.log(Level.WARNING,"Error ", e); } } public static void main(String[] args) { // 调用JavaFX启动类的launch方法 RunFrame.launch(RunFrame.class, args); } }
2. 修正RunFrame中的日志配置读取
同样将RunFrame中的日志配置读取改为从classpath加载,避免打包后找不到文件:
public class RunFrame extends Application { static Logger LOGGER; static { try(InputStream ins = RunFrame.class.getClassLoader().getResourceAsStream("log.config")) { if (ins != null) { LogManager.getLogManager().readConfiguration(ins); } LOGGER = Logger.getLogger(RunFrame.class.getName()); } catch (IOException e) { System.err.println("日志配置加载失败: " + e.getMessage()); LOGGER = Logger.getLogger(RunFrame.class.getName()); LOGGER.log(Level.WARNING,"Error ", e); } } public static void main(String[] args) { launch(args); } @Override public void start(Stage stage) { try { FXMLLoader loader = new FXMLLoader(); URL xmlUrl = getClass().getResource("/RunFrameScene.fxml"); loader.setLocation(xmlUrl); Parent root = loader.load(); stage.setTitle("App"); stage.getIcons().add(new Image(RunFrame.class.getClassLoader().getResourceAsStream("logo.png"))); stage.setScene(new Scene(root)); stage.show(); LOGGER.log(Level.INFO,"Success "); } catch (Exception e) { LOGGER.log(Level.SEVERE,"Error", e); } } }
二、配置Maven打包插件
要生成可直接运行的Jar,需添加javafx-maven-plugin处理JavaFX模块依赖,也可搭配maven-shade-plugin生成包含所有依赖的胖Jar。修改pom.xml如下:
<?xml version='1.0'?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.apache.activemq.examples.broker</groupId> <artifactId>jms-examples</artifactId> <version>2.27.1</version> </parent> <artifactId>jmx</artifactId> <packaging>jar</packaging> <name>FrameApplication</name> <dependencies> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-nop</artifactId> <version>1.7.36</version> </dependency> <dependency> <groupId>org.openjfx</groupId> <artifactId>javafx-controls</artifactId> <version>19</version> </dependency> <dependency> <groupId>org.openjfx</groupId> <artifactId>javafx-fxml</artifactId> <version>19</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> <version>3.0.5</version> </dependency> </dependencies> <build> <plugins> <!-- JavaFX打包插件,生成包含JRE的可执行镜像 --> <plugin> <groupId>org.openjfx</groupId> <artifactId>javafx-maven-plugin</artifactId> <version>0.0.8</version> <configuration> <mainClass>FrameRunApp</mainClass> <launcher>app</launcher> <jlinkImageName>App</jlinkImageName> <jlinkZipName>App</jlinkZipName> <!-- 可选:指定目标平台,如win、linux、mac --> <!-- <platforms> <platform>win</platform> <platform>linux</platform> <platform>mac</platform> </platforms> --> </configuration> <executions> <execution> <id>default-cli</id> <phase>package</phase> <goals> <goal>run</goal> <goal>jlink</goal> </goals> </execution> </executions> </plugin> <!-- Maven Shade插件,生成包含所有依赖的胖Jar --> <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> <transformers> <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"> <mainClass>FrameRunApp</mainClass> </transformer> </transformers> </configuration> </execution> </executions> </plugin> </plugins> </build> </project>
三、打包并运行
1. 生成包含JRE的可执行镜像(推荐)
在命令行执行:
mvn clean package
执行完成后,target目录下会生成App目录(或zip包),用户直接运行目录中的app.exe(Windows)或app(Linux/Mac)即可,无需额外安装JDK/JRE。
2. 生成胖Jar
执行相同命令后,target目录下会生成形如jmx-2.27.1-shaded.jar的文件,用户可直接双击运行,或通过命令启动:
java -jar jmx-2.27.1-shaded.jar
四、注意事项
- 确保
log.config、RunFrameScene.fxml、logo.png等资源文件均放在src/main/resources目录下,打包后会自动加入classpath - 若用户系统未安装JavaFX运行时,jlink生成的镜像已包含所需模块,无需额外配置;胖Jar则要求用户系统有兼容的JDK/JRE(需包含JavaFX)
内容的提问来源于stack exchange,提问作者user21871375
相关产品推荐
相关产品推荐

