使用Maven构建JavaFX可双击运行Jar包遇到的问题
问题解决:非模块化JavaFX应用Maven警告及双击Jar运行方案
一、解决Maven依赖警告
[WARNING] Failed to build parent project for org.openjfx:javafx-controls:jar:17.0.10 警告的核心原因是JavaFX依赖分平台(win/linux/mac)发布,未指定平台分类器时Maven无法拉取完整依赖包。
修复方案
在pom.xml中添加Maven配置文件,自动匹配当前操作系统的JavaFX依赖:
<properties> <!-- 新增默认分类器,可由profile自动覆盖 --> <javafx.classifier>win</javafx.classifier> </properties> <profiles> <profile> <id>windows</id> <activation> <os> <family>windows</family> </os> </activation> <properties> <javafx.classifier>win</javafx.classifier> </properties> </profile> <profile> <id>linux</id> <activation> <os> <family>linux</family> </os> </activation> <properties> <javafx.classifier>linux</javafx.classifier> </properties> </profile> <profile> <id>mac</id> <activation> <os> <family>mac</family> </os> </activation> <properties> <javafx.classifier>mac</javafx.classifier> </properties> </profile> </profiles>
然后修改所有JavaFX依赖,添加分类器参数:
<dependency> <groupId>org.openjfx</groupId> <artifactId>javafx-controls</artifactId> <version>${javafx.version}</version> <classifier>${javafx.classifier}</classifier> </dependency> <dependency> <groupId>org.openjfx</groupId> <artifactId>javafx-fxml</artifactId> <version>${javafx.version}</version> <classifier>${javafx.classifier}</classifier> </dependency> <dependency> <groupId>org.openjfx</groupId> <artifactId>javafx-graphics</artifactId> <version>${javafx.version}</version> <classifier>${javafx.classifier}</classifier> </dependency>
二、实现双击运行的Jar包
maven-assembly-plugin无法正确处理JavaFX的模块依赖,导致双击时JVM无法加载JavaFX核心类。推荐使用maven-shade-plugin替代,它能整合模块信息并生成可直接运行的Jar。
替换插件配置
移除原有的maven-assembly-plugin和maven-jar-plugin,添加以下配置:
<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> <shadedArtifactAttached>true</shadedArtifactAttached> <shadedClassifierName>all</shadedClassifierName> <transformers> <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"> <mainClass>${mainClass}</mainClass> <manifestEntries> <Automatic-Module-Name>com.BO</Automatic-Module-Name> </manifestEntries> </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>
主类要求
确保你的主类main.Main符合以下任一条件:
- 直接继承
javafx.application.Application并实现start()方法; - 普通类的
main方法中调用JavaFX启动器:
public class Main { public static void main(String[] args) { javafx.application.Application.launch(YourFXApplication.class, args); } }
三、跨设备运行进阶方案(推荐)
如果需要在未安装JDK/JRE的设备上运行,使用javafx-maven-plugin的jlink目标生成自包含应用包,包含专属JRE和所有依赖:
<plugin> <groupId>org.openjfx</groupId> <artifactId>javafx-maven-plugin</artifactId> <version>0.0.8</version> <configuration> <mainClass>${mainClass}</mainClass> <jlinkImageName>BO-App</jlinkImageName> <jlinkZipName>BO-App-Zip</jlinkZipName> <launcher>BO-Launcher</launcher> </configuration> <executions> <execution> <id>jlink</id> <goals> <goal>jlink</goal> </goals> </execution> </executions> </plugin>
执行mvn clean jlink后,target/BO-App目录会生成对应平台的可执行文件(Windows为.exe、Linux为.sh、Mac为.app),双击即可运行。
四、完整修改后的pom.xml
<groupId>com.BO</groupId> <artifactId>BO</artifactId> <version>1.0-SNAPSHOT</version> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <junit.version>5.9.2</junit.version> <itext.version>8.0.5</itext.version> <javafx.version>17.0.10</javafx.version> <mainClass>main.Main</mainClass> <javafx.classifier>win</javafx.classifier> </properties> <profiles> <profile> <id>windows</id> <activation> <os> <family>windows</family> </os> </activation> <properties> <javafx.classifier>win</javafx.classifier> </properties> </profile> <profile> <id>linux</id> <activation> <os> <family>linux</family> </os> </activation> <properties> <javafx.classifier>linux</javafx.classifier> </properties> </profile> <profile> <id>mac</id> <activation> <os> <family>mac</family> </os> </activation> <properties> <javafx.classifier>mac</javafx.classifier> </properties> </profile> </profiles> <repositories> <repository> <id>maven-repo-itext</id> <url>https://repo.itextsupport.com/nexus/content/groups/public/</url> </repository> <repository> <id>openjfx</id> <url>https://openjfx.io/repo</url> </repository> </repositories> <dependencies> <dependency> <groupId>net.sourceforge.jtds</groupId> <artifactId>jtds</artifactId> <version>1.3.1</version> </dependency> <dependency> <groupId>com.microsoft.sqlserver</groupId> <artifactId>mssql-jdbc</artifactId> <version>8.4.1.jre8</version> </dependency> <dependency> <groupId>com.itextpdf</groupId> <artifactId>itextpdf</artifactId> <version>5.5.13.4</version> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>5.2.3</version> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</artifactId> <version>5.2.3</version> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml-schemas</artifactId> <version>4.1.2</version> </dependency> <dependency> <groupId>org.apache.xmlbeans</groupId> <artifactId>xmlbeans</artifactId> <version>5.1.1</version> </dependency> <dependency> <groupId>com.itextpdf</groupId> <artifactId>kernel</artifactId> <version>8.0.5</version> </dependency> <dependency> <groupId>com.itextpdf</groupId> <artifactId>layout</artifactId> <version>8.0.5</version> </dependency> <dependency> <groupId>org.openjfx</groupId> <artifactId>javafx-controls</artifactId> <version>${javafx.version}</version> <classifier>${javafx.classifier}</classifier> </dependency> <dependency> <groupId>org.openjfx</groupId> <artifactId>javafx-fxml</artifactId> <version>${javafx.version}</version> <classifier>${javafx.classifier}</classifier> </dependency> <dependency> <groupId>org.openjfx</groupId> <artifactId>javafx-graphics</artifactId> <version>${javafx.version}</version> <classifier>${javafx.classifier}</classifier> </dependency> <dependency> <groupId>org.junit.jupiter</groupId> <artifactId>junit-jupiter-api</artifactId> <version>${junit.version}</version> <scope>test</scope> </dependency> <dependency> <groupId>org.junit.jupiter</groupId> <artifactId>junit-jupiter-engine</artifactId> <version>${junit.version}</version> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.11.0</version> <configuration> <source>22</source> <target>22</target> </configuration> </plugin> <plugin> <groupId>org.openjfx</groupId> <artifactId>javafx-maven-plugin</artifactId> <version>0.0.8</version> <configuration> <mainClass>${mainClass}</mainClass> <jlinkImageName>BO-App</jlinkImageName> <jlinkZipName>BO-App-Zip</jlinkZipName> <launcher>BO-Launcher</launcher> </configuration> <executions> <execution> <id>default-cli</id> <goals> <goal>run</goal> </goals> </execution> <execution> <id>jlink</id> <goals> <goal>jlink</goal> </goals> </execution> </executions> </plugin> <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> <shadedArtifactAttached>true</shadedArtifactAttached> <shadedClassifierName>all</shadedClassifierName> <transformers> <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"> <mainClass>${mainClass}</mainClass> <manifestEntries> <Automatic-Module-Name>com.BO</Automatic-Module-Name> </manifestEntries> </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>
五、使用说明
- 执行
mvn clean package,Maven自动匹配当前平台依赖,警告消失,target目录生成BO-1.0-SNAPSHOT-all.jar,双击即可运行; - 执行
mvn clean jlink,生成自包含应用包,可直接在对应平台分发运行,无需额外安装JDK。
内容的提问来源于stack exchange,提问作者David Carmona Arrabal
相关产品推荐
相关产品推荐

