毕设7:JavaFX应用打包

Posted on 2024-03-14 21:37  Capterlliar  阅读(209)  评论(0编辑  收藏  举报

前情提要:使用java模块化写了一个javafx应用,和非模块化打包不一样。

java版本:java17

javafx-version: 21.0.1


 

1. Java模块化打包配置

试图打包,出现报错:找不到模块javafx.control

仔细一看,module-info.java里所有模块都找不到

解决:maven-compiler-plugin版本太低,要高于哪个版本才能,具体哪个版本忘了,3.8.1可行。

 

继续点击package,报错:找不到符号

大片的找不到符号,观察一下是Lombok注解的Getter等部分找不到符号。那么是Lombok配置不对。

搜索一下发现要下Lombok插件,但这个插件在2022版本IDEA里搜索不到。于是去官网下载:Lombok

但官网下完还要改一改版本。打开IDEA的about,找到版本号:Build #IU-223.8214.52, built on December 20, 2022,也就是223.8214.52。

然后进入下载好的zip,用winRAR,或者别的什么解压软件打开lombok-plugin-0.34-2020.2.jar,进入META-INF,打开plugin.xml,如下:

在倒数第二行的since-build那里改成对应的版本号,后面的until-build没找到,填大一点就可以,然后安装到IDEA里。

装完了发现还是找不到符号,最后发现要在maven-compiler-plugin里加几行配置(完整xml见末尾):

                   <annotationProcessorPaths>
                        <path>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                            <version>${lombok.version}</version>
                        </path>
                    </annotationProcessorPaths>        

然后可以顺利打包。Lombok插件需不需要不确定。

2. jlink

接下来觉得jre太大,想要用jlink链接一个包出来。这也是模块化后可以用的功能。虽然最后打出来的包有150M比直接导出70M的jre还大完全没有用,但还是记一下。

加一个javafx-maven-plugin的插件,然后点击jlink:

报错:Error: Error reading module: xxxxx/xxx/target

点进源码里试图来一些高深的debug,未果。搜到一个相关的issue:jlink fails reading module #113

意思是如果没指定jlink运行路径,它会自己找到java home然后运行jlink。当前环境变量里的java版本是java8,但这个项目是java17,所以报错了。然而在环境变量里改过来还是不行,最后需要加一个javafx-maven-plugin的配置:

<jlinkExecutable>D:\Java\java17\bin\jlink</jlinkExecutable>

就是在java bin目录下找到jlink填进去

 

然后遇到新的报错,甚至是乱码:����: pdfbox路径 ��

很崩溃,刚好收到未来上班公司邮件,先签个卖身契缓解一下情绪(?

之前搜资料的时候有看到不是所有包都模块化,也就是有module-info的。显然pdfbox就没有module-info。为了jlink我们得给它注入一个:jar的module-info模块信息注入

这篇博客很完善了,特别注意存一下原来的jar。

然后对log4j也注入一下,jlink完成。从jdk里生成jre倒也是用的同样方法:

bin\jlink.exe --module-path jmods --add-modules java.desktop --output jre

3. 打包为exe

现在我们有jar包,有jre,放到exe4j里合一下,发现还缺了点依赖。接下来加一个插件maven-shade-plugin。理论上maven-assembly-plugin也可以,但我们用到了ikonli,一个javafx的icon包,用assembly打包会缺资源,详见:Error using the Ikonli font library java.lang.UnsupportedOperationException #11

现在有了带依赖的jar包,可以和jre放一起,合成能在没有java环境里跑的应用程序。

4. 另外的打包方式

Gradle

gradle的javafx打包插件更新更及时一点,但没试。

Graalvm

使用 GraalVM 将纯 JavaFX 项目打包成 EXE

简而言之要下一个VS2022提供环境,这位更是重量级。


 

完整但jlink配置完全多余的pom.xml:

<?xml version="1.0" encoding="UTF-8"?>
<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/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>PdfPaperTool</artifactId>
    <version>1.0</version>

    <properties>
        <maven.compiler.source>17</maven.compiler.source>
        <maven.compiler.target>17</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

        <javafx-version>21.0.1</javafx-version>
        <lombok.version>1.18.20</lombok.version>
    </properties>


    <dependencies>
        <!--javafx icon-->
        <dependency>
            <groupId>org.kordamp.ikonli</groupId>
            <artifactId>ikonli-fontawesome-pack</artifactId>
            <version>12.3.1</version>
        </dependency>
        <dependency>
            <groupId>org.kordamp.ikonli</groupId>
            <artifactId>ikonli-javafx</artifactId>
            <version>12.3.1</version>
        </dependency>

        <!--Explanation of JavaFX modules: https://openjfx.io/javadoc/17/-->
        <!--javafx.base and javafx.graphics are automatically pulled when
        javafx.control imported-->
        <dependency>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-controls</artifactId>
            <version>${javafx-version}</version>
        </dependency>
        <dependency>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-fxml</artifactId>
            <version>${javafx-version}</version>
        </dependency>
        <dependency>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-swing</artifactId>
            <version>${javafx-version}</version>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>${lombok.version}</version>
            <scope>provided</scope>
        </dependency>

        <dependency>
            <groupId>org.apache.pdfbox</groupId>
            <artifactId>pdfbox</artifactId>
            <version>2.0.24</version>
        </dependency>

        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <source>17</source>
                    <target>17</target>
                    <encoding>UTF-8</encoding>
                    <annotationProcessorPaths>
                        <path>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                            <version>${lombok.version}</version>
                        </path>
                    </annotationProcessorPaths>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-shade-plugin</artifactId>
                <version>3.5.2</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>shade</goal>
                        </goals>
                        <configuration>
                            <transformers>
                                <transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/>
                                <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                                    <mainClass>com.pdfTool.AppRun</mainClass>
                                </transformer>
                            </transformers>
                        </configuration>
                    </execution>
                </executions>
            </plugin>

            <plugin>
                <groupId>org.openjfx</groupId>
                <artifactId>javafx-maven-plugin</artifactId>
                <version>0.0.8</version>
                <executions>
                    <execution>
                        <id>default-cli</id>
                        <configuration>
                            <source>17</source>
                            <target>17</target>
                            <mainClass>com.pdfTool/com.pdfTool.AppRun</mainClass>
                            <launcher>app</launcher>
                            <jlinkZipName>app</jlinkZipName>
                            <jlinkImageName>app</jlinkImageName>
                            <noManPages>true</noManPages>
                            <stripDebug>true</stripDebug>
                            <noHeaderFiles>true</noHeaderFiles>
                            <jlinkExecutable>D:\Java\java17\bin\jlink</jlinkExecutable>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>
View Code