• JFX11+Maven+IDEA 发布跨平台应用的完美解决方案


    JFX11+Maven+IDEA 发布跨平台应用的完美解决方案 - 知乎

    1. <dependencies>
    2. <dependency>
    3. <groupId>org.openjfx</groupId>
    4. <artifactId>javafx-base</artifactId>
    5. <version>11</version>
    6. <classifier>linux</classifier>
    7. </dependency>
    8. <dependency>
    9. <groupId>org.openjfx</groupId>
    10. <artifactId>javafx-base</artifactId>
    11. <version>11</version>
    12. <classifier>win</classifier>
    13. </dependency>
    14. <dependency>
    15. <groupId>org.openjfx</groupId>
    16. <artifactId>javafx-controls</artifactId>
    17. <version>11</version>
    18. <classifier>linux</classifier>
    19. </dependency>
    20. <dependency>
    21. <groupId>org.openjfx</groupId>
    22. <artifactId>javafx-controls</artifactId>
    23. <version>11</version>
    24. <classifier>win</classifier>
    25. </dependency>
    26. <dependency>
    27. <groupId>org.openjfx</groupId>
    28. <artifactId>javafx-fxml</artifactId>
    29. <version>11</version>
    30. <classifier>linux</classifier>
    31. </dependency>
    32. <dependency>
    33. <groupId>org.openjfx</groupId>
    34. <artifactId>javafx-fxml</artifactId>
    35. <version>11</version>
    36. <classifier>win</classifier>
    37. </dependency>
    38. <dependency>
    39. <groupId>org.openjfx</groupId>
    40. <artifactId>javafx-graphics</artifactId>
    41. <version>11</version>
    42. <classifier>linux</classifier>
    43. </dependency>
    44. <dependency>
    45. <groupId>org.openjfx</groupId>
    46. <artifactId>javafx-graphics</artifactId>
    47. <version>11</version>
    48. <classifier>win</classifier>
    49. </dependency>
    50. </dependencies>
    1. <properties>
    2. <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    3. <maven.compiler.source>11</maven.compiler.source>
    4. <maven.compiler.target>11</maven.compiler.target>
    5. </properties

    -------------------------------------------------------------------------------------------------------------------------------

    原文

    1 概述

    前几天写了两篇关于JFX+IDEA打包跨平台应用的文章,这篇是使用IDEA自带功能打包的,这篇是使用Maven进行打包的,但是效果不太满意,因为从JDK9开始实现模块化,同时JFX部分从JDK中独立出来了,也就是说需要默认JDK不再自带JFX。这意味着外部依赖需要手动处理module-info.java,这是一件非常麻烦的事情。

    1.1 不使用Maven

    其实不使用Maven也能打包发布跨平台JFX应用,但是没有使用Maven的话,虽然打包出来能直接运行无需jre环境,但是,管理依赖确实麻烦,在使用jlink打包一些外部的jar时,对于一些比较简单的jar还是比较舒服的,参照这里

    首先去下载jar,接着生成module-info.java,然后使用jdeps检查依赖,添加对应的jar到路径中,编译生成module-info.java接着更新原来的jar即可。看起来简单,但是笔者碰到了okhttp这种jar,依赖简直环环相扣导致笔者放弃了这种方式。

    1.2 使用Maven

    使用Maven可以完美解决依赖问题,多亏强大的pom.xml,几行就可以解决依赖问题,但是,还是需要手动处理module-info.java,而且IDEA文档明确表明仅支持Java8的打包为jar:

    因此,这篇文章采取一种最简单的方式利用Maven打包发布JFX11应用。

    2 新建Maven工程

    默认即可,问题不大。

    3 添加依赖

    1. <dependencies>
    2. <dependency>
    3. <groupId>org.openjfx</groupId>
    4. <artifactId>javafx-base</artifactId>
    5. <version>11</version>
    6. <classifier>linux</classifier>
    7. </dependency>
    8. <dependency>
    9. <groupId>org.openjfx</groupId>
    10. <artifactId>javafx-base</artifactId>
    11. <version>11</version>
    12. <classifier>win</classifier>
    13. </dependency>
    14. <dependency>
    15. <groupId>org.openjfx</groupId>
    16. <artifactId>javafx-controls</artifactId>
    17. <version>11</version>
    18. <classifier>linux</classifier>
    19. </dependency>
    20. <dependency>
    21. <groupId>org.openjfx</groupId>
    22. <artifactId>javafx-controls</artifactId>
    23. <version>11</version>
    24. <classifier>win</classifier>
    25. </dependency>
    26. <dependency>
    27. <groupId>org.openjfx</groupId>
    28. <artifactId>javafx-fxml</artifactId>
    29. <version>11</version>
    30. <classifier>linux</classifier>
    31. </dependency>
    32. <dependency>
    33. <groupId>org.openjfx</groupId>
    34. <artifactId>javafx-fxml</artifactId>
    35. <version>11</version>
    36. <classifier>win</classifier>
    37. </dependency>
    38. <dependency>
    39. <groupId>org.openjfx</groupId>
    40. <artifactId>javafx-graphics</artifactId>
    41. <version>11</version>
    42. <classifier>linux</classifier>
    43. </dependency>
    44. <dependency>
    45. <groupId>org.openjfx</groupId>
    46. <artifactId>javafx-graphics</artifactId>
    47. <version>11</version>
    48. <classifier>win</classifier>
    49. </dependency>
    50. </dependencies>

    需要在哪个平台在classifier中指定即可。这里是Linuxwin

    同时指定编码与JDK:

    1. <properties>
    2. <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    3. <maven.compiler.source>11</maven.compiler.source>
    4. <maven.compiler.target>11</maven.compiler.target>
    5. </properties>

    否则会报错:

    4 新建Main

    新建一个包再新建Main.javaLauncher.java以及Main.fxml

    Main.java如下:

    1. package com.test;
    2. import javafx.application.Application;
    3. import javafx.fxml.FXMLLoader;
    4. import javafx.scene.Parent;
    5. import javafx.scene.Scene;
    6. import javafx.stage.Stage;
    7. public class Main extends Application {
    8. public void start(Stage stage) throws Exception {
    9. Parent root = FXMLLoader.load(getClass().getResource("/Main.fxml"));
    10. Scene scene = new Scene(root);
    11. stage.setScene(scene);
    12. stage.setTitle("Hello World");
    13. stage.show();
    14. }
    15. public static void main(String[] args) {
    16. launch(args);
    17. }
    18. }

    Launcher.java

    1. package com.test;
    2. public class Launcher {
    3. public static void main(String[] args) {
    4. Main.main(args);
    5. }
    6. }

    Main.fxml

    1. <?xml version="1.0" encoding="UTF-8"?>
    2. <?import javafx.scene.control.*?>
    3. <?import javafx.scene.layout.*?>
    4. <?import javafx.scene.text.*?>
    5. <AnchorPane prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/10.0.2-internal"
    6. xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.test.Main">
    7. <Label layoutX="228.0" layoutY="185.0" text="Hello World">
    8. <font>
    9. <Font size="25.0"/>
    10. </font>
    11. </Label>
    12. </AnchorPane>

    注意getResource中的fxml路径,Main.fxml文件放在resources下,直接通过根路径读取:

    getResource("/Main.fxml");

    5 添加运行配置

    此时应该是没有运行配置的状态,点击Add Configuration

    添加Application

    添加Launcher类作为Main class

    这时候run就没问题了:

    6 使用默认Maven打包

    虽然现在可以运行了,但是,如果直接使用默认的Maven打包的话:

    target下有一个jar,直接右键运行:

    会提示no main manifest attribute

    也就是找不到Manifest中入口类。

    jar实际上是一个class的压缩包,与zip的区别是jar包含了一个MANIFEST.MFMANIFEST.MFMETA-INF下,一个示例文件如下:

    有点类似与键值对的格式,MANIFEST.MF包含了jar文件的内容描述,并在运行时向JVM提供应用程序信息。注意该文件有严格的格式限制,比如第一行不能为空,行与行之间不能存在空行。

    一个暴力的解决办法是直接解压jar并修改里面的MANIFEST.MF,添加

    Main-Class: com.test.Launcher

    但是这样会报找不到Application类的异常:

    7 添加新的打包插件

    理论上来说,只需要jar包内的相同目录下提供了javafx的jar或者class文件就不会抛出异常了,但是,如果依赖很多需要一个一个添加,这是一个痛苦的过程。

    所以,为了优雅地解决这个问题,引入一个叫maven-shade-plugin的插件即可:

    1. <build>
    2. <plugins>
    3. <plugin>
    4. <groupId>org.apache.maven.plugins</groupId>
    5. <artifactId>maven-shade-plugin</artifactId>
    6. <version>3.2.2</version>
    7. <executions>
    8. <execution>
    9. <phase>package</phase>
    10. <goals>
    11. <goal>shade</goal>
    12. </goals>
    13. <configuration>
    14. <transformers>
    15. <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
    16. <mainClass>com.test.Launcher</mainClass>
    17. </transformer>
    18. </transformers>
    19. </configuration>
    20. </execution>
    21. </executions>
    22. </plugin>
    23. </plugins>
    24. </build>

    最新版本请到官方Github查看,使用时只需要修改:

    <mainClass>xxx.xxx.xxx</mainClass>

    修改为程序入口类。

    8 打包

    此时再从右侧栏打包选中Mavenpackage即可:

    但是会有警告:

    因为一些class文件重复了,但是也提到了通常来说这是没有危害的并且可以跳过警告,或者修改pom.xml去手动排除某些依赖。

    9 运行

    直接在IDEA中右键运行或者-jar运行,可以看到没有异常了:

    相比起原来自带的Maven打包插件,主要是多了javafx的一些class以及对应平台所需要的一些动态库文件等,比如Windows上的.dllLinux上的.so文件。

    这样一个跨平台的JFX jar包就制作好了,只需

    java -jar

    即可跨平台运行。

  • 相关阅读:
    ConfigMaps in K8s
    【校招VIP】线上实习 推推 书籍详情模块 产品脑图周最佳
    云计算学习笔记——第三章 计算虚拟化[二]
    【Redis】关于过期数据清除的一些策略
    实验18.RIP路由引入
    矩阵置零(C++解法)
    Java学习Go(入门)
    单体应用、SOA架构、微服务架构的对比
    未来 20 年 12 大发展趋势
    ai智能机器人 okcc vos3000运营风控那些事
  • 原文地址:https://blog.csdn.net/xiaoerbuyu1233/article/details/133693889