如何用Maven打包含Apache Tika的JavaFX17应用为独立EXE?
解决方案:JavaFX + Apache Tika 打包独立EXE遇到的签名与模块问题
问题根源
- 签名文件冲突:BouncyCastle依赖携带的签名文件(.SF/.RSA/.DSA)在打包合并时触发
SecurityException - 自动模块不兼容jlink:Tika、BouncyCastle等依赖为自动模块,jlink要求显式模块定义
- 手动删除签名文件会破坏BouncyCastle的功能,导致Tika无法解析文档
方案1:Maven Shade打包单Jar + Launch4j生成EXE
这是最直接的解决方案,通过Shade插件过滤冲突签名文件,再用Launch4j捆绑JRE生成独立EXE。
1. 修改POM配置
替换原有build插件,添加Shade插件并配置签名过滤:
<build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.11.0</version> <configuration> <source>17</source> <target>17</target> </configuration> </plugin> <!-- 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>com.sky.tikaparse.TikaAppLauncher</mainClass> </transformer> </transformers> <!-- 过滤所有依赖的签名文件,避免冲突 --> <filters> <filter> <artifact>*:*</artifact> <excludes> <exclude>META-INF/*.SF</exclude> <exclude>META-INF/*.RSA</exclude> <exclude>META-INF/*.DSA</exclude> </excludes> </filter> </filters> </configuration> </execution> </executions> </plugin> <!-- 保留JavaFX插件用于IDE运行(可选) --> <plugin> <groupId>org.openjfx</groupId> <artifactId>javafx-maven-plugin</artifactId> <version>0.0.8</version> <configuration> <mainClass>com.sky.tikaparse/com.sky.tikaparse.TikaAppLauncher</mainClass> </configuration> </plugin> </plugins> </build>
2. 执行打包
运行命令:
mvn clean package
在target目录下会生成包含所有依赖的单Jar文件。
3. 生成独立EXE
使用开源工具Launch4j:
- 配置Jar路径指向打包好的单Jar文件
- 在JRE选项中选择本地OpenJDK17路径,开启"捆绑JRE"功能
- 设置EXE文件名、图标等参数,生成可独立运行的EXE
方案2:jpackage官方原生打包(处理自动模块)
若需官方原生镜像,需为自动模块添加显式模块定义:
1. 添加模块描述文件
在src/main/java下创建module-info.java:
module com.sky.tikaparse { requires javafx.controls; requires javafx.fxml; requires org.apache.tika.core; requires org.apache.tika.parsers.standard.package; requires org.bouncycastle.provider; requires net.sourceforge.tess4j; requires org.apache.poi.poi; requires org.apache.poi.ooxml; requires org.slf4j; requires com.fasterxml.jackson.dataformat.yaml; requires org.apache.commons.lang3; requires org.apache.logging.log4j.core; opens com.sky.tikaparse to javafx.fxml; exports com.sky.tikaparse; }
2. 修改POM配置
添加jpackage插件与依赖复制插件:
<build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.11.0</version> <configuration> <source>17</source> <target>17</target> <modulepath>${project.build.directory}/dependency-jars</modulepath> </configuration> </plugin> <!-- JavaFX + jpackage插件 --> <plugin> <groupId>org.openjfx</groupId> <artifactId>javafx-maven-plugin</artifactId> <version>0.0.8</version> <configuration> <mainClass>com.sky.tikaparse/com.sky.tikaparse.TikaAppLauncher</mainClass> <launcher>app</launcher> <jlinkImageName>app</jlinkImageName> <jpackageAppName>TikaParse</jpackageAppName> <jpackageInstallerType>exe</jpackageInstallerType> <noManPages>true</noManPages> <stripDebug>true</stripDebug> <noHeaderFiles>true</noHeaderFiles> <modulePath> <path>${project.build.directory}/dependency-jars</path> </modulePath> </configuration> <executions> <execution> <id>default-cli</id> <phase>package</phase> <goals> <goal>jlink</goal> <goal>jpackage</goal> </goals> </execution> </executions> </plugin> <!-- 复制非JavaFX依赖到指定目录 --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-dependency-plugin</artifactId> <version>3.6.0</version> <executions> <execution> <id>copy-dependencies</id> <phase>prepare-package</phase> <goals> <goal>copy-dependencies</goal> </goals> <configuration> <outputDirectory>${project.build.directory}/dependency-jars</outputDirectory> <excludeGroupIds>org.openjfx</excludeGroupIds> </configuration> </execution> </executions> </plugin> </plugins> </build>
3. 执行打包
运行命令:
mvn clean package
在target目录下会生成包含JRE和EXE的原生安装包。
关键验证步骤
打包完成后,先运行Jar确认功能正常:
java -jar target/TikaParse-1.0-SNAPSHOT.jar
确保Tika能正常解析文档后,再生成EXE。
内容的提问来源于stack exchange,提问作者CFJR Corporativo
相关产品推荐
相关产品推荐

