JavaFX打包exe+Wind+Mac+Linux多平台分发等等

JavaFX打包exe+Wind+Mac+Linux多平台分发等等

由于此教程相对复杂,适合对java有一定掌握的同学操作,于是我又写了一篇用idea简单打包exe的教程,文章地址:https://blog.csdn.net/weixin_44480167/article/details/121374415
新手请访问上面的文章

如果使用java -jar xxx.jar一堆窗口不好看,分发不方便,我们可以使用packr来打包exe,网上教打包exe的基本上都是用什么exe4j麻烦还不知道干啥的,基本不成功!现在是2021年11月14日15:21:51
思路可以参考这篇文章:https://blog.csdn.net/weixin_44480167/article/details/120895260

下面我将一个简单javafx的demo打包成exe,若你想打包成mac、linux什么的可以按照我下面的思路试试,家境贫寒无法测试mac,若你成功了请告诉我,嘿嘿。
环境:jdk17 + javafx17
保姆式打包教程、保姆式打包教程、保姆式打包教程、保姆式打包教程、保姆式打包教程、保姆式打包教程、
多图警告、多图警告、多图警告、多图警告、多图警告、多图警告、

一、创建一个demo

你可以使用idea2021.2.x高版本创建一个demo,可参考文章:https://blog.csdn.net/weixin_44480167/article/details/121316802
在这里插入图片描述
这里我将使用普通的Maven项目,第一步肯定是依赖啦:

    <properties>
        <maven.compiler.source>17</maven.compiler.source>
        <maven.compiler.target>17</maven.compiler.target>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-controls</artifactId>
            <version>17.0.1</version>
        </dependency>
        <dependency>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-fxml</artifactId>
            <version>17.0.1</version>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <source>17</source>
                    <target>17</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
        </plugins>
    </build>

编写一个:resources/fxml/fxml_demo.fxml

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.AnchorPane?>

<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="209.0"
            prefWidth="250.0" xmlns="http://javafx.com/javafx/16" xmlns:fx="http://javafx.com/fxml/1"
            fx:controller="top.lingkang.FxmlController">
    <children>
        <Button fx:id="btn" layoutX="46.0" layoutY="51.0" mnemonicParsing="false" text="获取当前时间"/>
        <TextField fx:id="text" layoutX="46.0" layoutY="86.0"/>
        <Label fx:id="lab" layoutX="46.0" layoutY="129.0" text="Label"/>
    </children>
</AnchorPane>

编写一个controller

import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;

import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.ResourceBundle;

/**
 * @author lingkang
 * @date 2021/11/14
 */
public class FxmlController implements Initializable {
    @FXML // 初始化时会自行绑定fxml里的id,注意变量命名=fxml里的id
    private Button btn;
    @FXML // 初始化时会自行绑定fxml里的id,注意变量命名=fxml里的id
    private TextField text;
    // 初始化时会自行绑定fxml里的id,注意变量命名=fxml里的id
    public Label lab;

    @Override
    public void initialize(URL url, ResourceBundle resourceBundle) {
        // 添加初始化事件
        btn.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent actionEvent) {
                SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                String date = format.format(new Date());
                // 将值赋予标签显示
                text.setText(date);
                lab.setText(date);
            }
        });
    }
}

编写启动入口main

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.layout.AnchorPane;
import javafx.stage.Stage;

import java.net.URL;

/**
 * @author lingkang
 * @date 2021/11/14
 */
public class FxmlDemo extends Application {
    @Override
    public void start(Stage stage) throws Exception {
        // 获取 Maven 项目 resources/fxml/fxml_demo.fxml 注意,无法识别横向,例如 fxml-demo.fxml
        URL resource = getClass().getResource("/fxml/fxml_demo.fxml");
        if (resource == null) {
            throw new RuntimeException("未找到fxml资源");
        }
        // 此时需要注意, fxml里最外层标签是 AnchorPane 故使用AnchorPane对象获取变量
        AnchorPane anchorPane = FXMLLoader.load(resource);
        // 将 AnchorPane 加入到场景
        stage.setScene(new Scene(anchorPane));
        stage.setTitle("openjfx17~");
        stage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }
}

run启动失败:
在这里插入图片描述

二、配置一个openjfx17

我们知道,javafx已经在jdk11还是9、10哪个版本来着,将此作为独立的GUI维护,并推荐使用OpenJFX。OpenJFX的下载地址:https://openjfx.cn/dl/我这里下载17.0.1zip版本。
将OpenJFX17解压到C:\Program Files\Java\javafx-sdk-17.0.1,
配置idea的application启动,添加启动vm参数,将模块引入:
--module-path "C:\Program Files\Java\javafx-sdk-17.0.1\lib" --add-modules javafx.controls,javafx.fxml
在这里插入图片描述
再运行一次:
在这里插入图片描述

三、将javafx项目打包jar

我们先将javafx项目打包成运行的jar,javafx11+独立出了GUI,打包jar有点特殊,需要将dll也打包!
先创建一个启动入口,打成的jar从这里启动,不能直接从编写的FxmlDemo.main启动!

package top.lingkang;

/**
 * @author lingkang
 * @date 2021/11/14
 */
public class App {
    public static void main(String[] args) {
        FxmlDemo.main(args);
    }
}

一定要先创建一个普通main去运行javafx的main

idea中 File》Proiect Structure》Libraries
1、先删除maven的依赖:
在这里插入图片描述
2、将openjfx的依赖添加进来:
在这里插入图片描述
3、按照第2步,将openjfx的window运行的dll库添加进来:
在这里插入图片描述
在这里插入图片描述
设置构建jar
在这里插入图片描述
选择启动类,上面新编写的App类
在这里插入图片描述
将dll添加进来:+ File
在这里插入图片描述
在这里插入图片描述
然后点OK,然后构建jar
在这里插入图片描述
Build
在这里插入图片描述
构建后运行这个jar
在这里插入图片描述
至此,javafx打包jar完毕!接下来是打包exe

那个警告是因为没有配置模块化module-info.java,忽略他即可。
在java16以上可以模块化开发:module-info.java,用idea2021.2.x直接初始化javafx项目就自动生成这个src/main/java/module-info.java,内容大概如下:

module top.lingkang.demo {
    requires javafx.controls;
    requires javafx.fxml;

    opens top.lingkang.demo to javafx.fxml;
    exports top.lingkang.demo;
}

四、packr打包exe

packr是可以多平台打包分发,所以我不算标题党,这里我只显示了win打包,因为家境贫寒Mac测试不了,你也可以寄一台Mac给我打包试试。
packr下载:https://github.com/libgdx/packr
下载好packr-all-4.0.0.jar
下载一个openjdk17,我在清华大学镜像站下载:https://mirrors.tuna.tsinghua.edu.cn/
Index of /AdoptOpenJDK/17/jdk/x64/windows/
将他们放一起
在这里插入图片描述
编写一个my-packr-config.json

{
    "platform": "windows64",
    "jdk": "./OpenJDK17U-jdk_x64_windows_hotspot_17.0.1_12.zip",
    "executable": "javaFX-demo",
    "classpath": [
        "demo2.jar"
    ],
    "mainclass": "top.lingkang.App",
    "vmargs": [
       "Xms32m","Xmx512m"
    ],
    "minimizejre": "soft",
    "output": "out-windows64"
}

若出现中文乱码可考虑在json的vmargs中添加"Dfile.encoding=utf-8"
在这里插入图片描述
cmd执行构建,

java -jar packr-all-4.0.0.jar my-packr-config.json
# 或者
java -jar -Dfile.encoding=utf-8 packr-all-4.0.0.jar my-packr-config.json

等待完成!
在这里插入图片描述
运行exe
在这里插入图片描述
没设置图标,嘿嘿!

压缩后大小有200多MB,如果选用java11的话估计在100MB以内,这里我提供一些大小压缩思路,例如将openjfx的dll直接放到openjdk17中,将减少jar的打包大小,当然啦,也有可能是packr-all-4.0.0.jar未支持jdk17,所有将整个openjdk17的jre放进去了,未实现删减!!那我们只能等等党,或者降低jdk版本啦!

若运行exe无任何事情发生,可以cmd运行 xxx.exe查看控制台输出的错误,根据错误解决。
在这里插入图片描述
上面的错误就是jar打包后无法识别resources的资源,可以考虑独立拿出fxml,调用时调用当前目录下的fxml/xxx.fxml。。或者使用压缩软件打开jar,调整目录位置。个人更推荐加载外部资源。。

五、一件三连

创作不易,写文章也花长时间,你觉得对你有帮助请给我点个赞!一健三连…谢谢啦!
创作不易,写文章也花长时间,你觉得对你有帮助请给我点个赞!一健三连…谢谢啦!
创作不易,写文章也花长时间,你觉得对你有帮助请给我点个赞!一健三连…谢谢啦!
你的点赞就是我的动力
你的点赞就是我的动力
你的点赞就是我的动力

<think>嗯,用户想创建一个包含JavaFX应用、JDK/JRE和MySQL的跨平台一键安装包。首先,我需要理解他们的需求。他们希望用户能够轻松安装,不需要预先安装JDK或者MySQL,对吧?所以安装包需要内嵌这些依赖,并且跨平台支持Windows、macOS和Linux。 首先,我应该考虑打包工具。之前用户提到的exe4j只能生成Windows的EXE文件,但跨平台的话可能需要其他工具。记得引用[2]里提到了Electron、QT、JavaFX这些跨平台方案,但这里用户已经用JavaFX了,所以需要打包工具支持多平台。 然后,JDK/JRE的捆绑。Java 9以后的jlink工具可以创建自定义运行时,这样可以把必要的模块打包进去,减少体积。或者使用jpackage,它是JDK自带的,能生成原生安装包,支持多个平台。jpackage可能是个好选择,因为它直接集成在JDK里,而且可以打包应用和JRE。 接下来是MySQL的问题。MySQL通常需要单独安装,但用户希望一键安装,所以可能需要将MySQL嵌入到应用中。可以考虑使用嵌入式数据库,比如H2或者MariaDB的嵌入式版本。不过用户明确提到MySQL,所以可能需要打包MySQL社区版,并在安装过程中自动安装配置。或者,使用Docker容器来运行MySQL,但这样会增加依赖,用户需要安装Docker,这可能不太方便。 然后,安装包制作工具。对于跨平台安装,可能需要不同的工具来处理各系统的打包。例如,Windows用Inno Setup,macOS用pkgbuild,Linux用deb/rpm。但用户想要一键安装,跨平台的,所以需要统一工具。可能推荐的工具是Install4j,它支持多平台安装包,并且可以包含JRE和第三方服务如MySQL。另外,IzPack也是一个选择,但配置可能复杂些。或者,jpackage结合脚本处理MySQL的安装。 步骤可能包括:1. 使用jlink/jpackage打包JavaFX应用和JRE;2. 集成MySQL的安装脚本或嵌入式版本;3. 使用安装包工具将所有东西打包成各平台的安装程序;4. 测试安装流程是否自动配置好数据库。 需要确保MySQL在安装过程中自动启动,并创建所需的数据库和用户。可能需要编写脚本,在安装后执行初始化操作。对于跨平台,脚本需要兼容不同系统,或者安装工具支持条件判断和执行不同脚本。 另外,引用[1]提到exe4j可以打包EXE并包含JDK,但仅限于Windows。用户需要跨平台,所以exe4j不合适。引用[2]提到JavaFX作为选项,所以继续使用JavaFX是正确的。引用[3]的MyBatis可能不相关,但用户可能已经在用,所以打包时需要考虑相关配置。 总结,可能的解决方案是使用jpackage打包应用和JRE,然后使用Install4j来创建安装包,里面包含应用、JRE和MySQL的安装脚本。或者,使用Docker Compose来编排应用和MySQL,但需要用户安装Docker,这可能不符合“一键安装”的要求。 需要进一步考虑如何将MySQL打包进去。或许在安装过程中下载MySQL社区版并静默安装,或者将MySQL的可执行文件打包进去,然后通过脚本启动。但需要注意许可问题,MySQL的GPL协议是否允许再分发。 最后,测试各个平台的安装包是否正常工作,确保数据库自动配置,应用能够连接。可能还需要处理不同系统的路径问题,比如Windows的Program Files,Linux的/opt等。</think>### 分步解决方案:创建跨平台JavaFX一键安装包 #### 一、工具选择与核心思路 1. **JavaFX应用打包** 使用 **JDK自带的jpackage工具**[^1],将JavaFX应用和JRE捆绑生成原生安装包(支持Windows/MSI、macOS/DMG、Linux/DEB/RPM)。 2. **MySQL集成方案** - **方案一(推荐)**:使用嵌入式数据库如**H2**或**SQLite**替代MySQL,简化部署。 - **方案二**:在安装包中捆绑MySQL社区版,通过脚本控制安装和初始化[^2]。 3. **跨平台安装包工具** - **Install4j**(商业工具):支持多平台安装包生成,可集成JRE、MySQL安装脚本和依赖库[^1]。 - **IzPack**(开源):需配合自定义脚本实现复杂逻辑。 --- #### 二、详细操作步骤(以Install4j为例) ##### 1. 准备JavaFX应用 - 确保项目为可执行JAR(Maven/Gradle构建时配置`<mainClass>`)。 - 使用`jlink`生成最小化JRE: ```bash jlink --add-modules java.base,javafx.controls,javafx.fxml --output ./custom-jre ``` ##### 2. 配置Install4j 1. **新建项目** 选择目标平台(Windows、macOS、Linux),设置应用名称、版本。 2. **添加JAR和JRE** - 主JAR文件:导入JavaFX生成的JAR。 - 捆绑JRE:选择`custom-jre`目录或让Install4j自动下载。 3. **集成MySQL** - **方法一(嵌入式)**:将H2/SQLite驱动加入依赖,代码中配置内存数据库。 - **方法二(独立MySQL)**: - 在安装包中添加MySQL安装文件(如Windows的`.msi`,Linux的`.tar.gz`)。 - 编写启动脚本自动执行MySQL安装和初始化: ```bash # Linux/macOS示例 tar -xzf mysql-8.0.33-linux-glibc2.12-x86_64.tar.gz ./mysql-8.0.33/bin/mysqld --initialize-insecure ./mysql-8.0.33/bin/mysqld_safe & ``` 4. **配置安装流程** - 添加文件释放操作:将MySQL和JAR释放到目标目录。 - 添加“运行脚本”动作:执行数据库初始化命令。 - 设置环境变量(如`JAVA_HOME`、数据库连接参数)。 ##### 3. 构建安装包 - 生成多平台安装文件(如Windows的EXEmacOS的APP、Linux的SH)。 - 测试安装流程是否自动启动应用和数据库。 --- #### 三、替代方案与优化 1. **使用Docker容器化** - 编写`Dockerfile`包含JavaFX应用、OpenJDK和MySQL: ```dockerfile FROM openjdk:17-jdk COPY ./app.jar /app/ RUN apt-get update && apt-get install -y mysql-server CMD service mysql start && java -jar /app/app.jar ``` - 用户需安装Docker后执行`docker-compose up`启动。 2. **jpackage + 脚本扩展** - 用jpackage生成基础安装包,添加Post-Install脚本启动MySQL: ```bash # jpackage配置示例 jpackage --name MyApp --input ./lib --main-jar app.jar \ --runtime-image ./custom-jre \ --install-dir /opt/MyApp \ --post-install-script ./setup_mysql.sh ``` --- #### 四、注意事项 1. **许可合规性** - MySQL社区版遵循GPL协议,需在安装包中声明。 2. **安装包体积** - 最小化JRE(约40-60MB) + MySQL(约200MB)可能导致安装包较大。 3. **跨平台兼容性** - 针对不同系统分别测试脚本权限、路径格式和依赖项。 ---
评论 16
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

凌康ACG

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值