我如何使一个独立的Windows可执行文件(. exe
)为我的JavaFX
项目(我写在IntelliJ IDEA),没有安装程序为我的程序?我希望用户下载. exe
文件并在没有安装程序的情况下开箱运行,即使他们的计算机上没有JRE。这有可能吗?到目前为止,我已经读了一些关于以下选项的文章:
一起复制。exe
。exe
文件
所以,如果我理解正确的话,这两个都不会帮助我。我找到了这篇和这篇文章,但它们没有涵盖我的具体情况。对不起,如果我问了一个愚蠢的问题,这是我第一次使用JavaGUI。
为此,您必须生成一个胖jar(如果您的java应用程序有依赖项),如果它没有依赖项,请保持原样,然后使用启动4j。要创建一个胖罐子,请执行以下操作:
>
<property name="store.jar.name" value="Master Data App"/>
<property name="store.dir" value="store"/>
<property name="store.jar" value="${store.dir}/${store.jar.name}.jar"/>
<echo message="Packaging ${application.title} into a single JAR at ${store.jar}"/>
<delete dir="${store.dir}"/>
<mkdir dir="${store.dir}"/>
<jar destfile="${store.dir}/temp_final.jar" filesetmanifest="skip">
<zipgroupfileset dir="dist" includes="*.jar"/>
<zipgroupfileset dir="dist/lib" includes="*.jar"/>
<manifest>
<attribute name="Main-Class" value="sheetupdown.SheetUpDown"/>
</manifest>
</jar>
<zip destfile="${store.jar}">
<zipfileset src="${store.dir}/temp_final.jar"
excludes="META-INF/*.SF, META-INF/*.DSA, META-INF/*.RSA"/>
</zip>
<delete file="${store.dir}/temp_final.jar"/>
在JavaIDE中,右键单击build。xml-
你会在商店文件夹中的项目中找到你的胖罐子。
开放式发射4J
指定输出文件(以.exe结尾)
指定你的胖罐子在哪里
(根据需要添加其他选项,如:图标,jre版本......)-选项-
单击构建包装器
绝对要求生成exe不是正确的做法,但如果必须这样做,那么https://docs.gluonhq.com/这是唯一合理的方法。否则,您应该结合jlink查看jpackage。忘了这些关于肥罐子和其他选择的话题吧。现在JavaFX应用程序不是这样构建的。
使用warp-Packer
从jlink创建的映像和应用启动器中创建一个exe
。
第一:
然后,创建一个单文件应用程序可执行文件。这可以通过一个命令完成(在单行上运行它,并使用您的值而不是%%
变量):
%WARP_DIR%\warp-packer
--arch windows-x64
--input_dir %APP_JLINK_IMAGE_DIR%
--exec %APP_JLINK_LAUNCHER_BAT_FILE%
--output %APP_SINGLE_EXECUTABLE_FILE_NAME%
该命令可以从命令行手动运行,也可以通过适当的构建工具插件自动运行。
可以使用最适合您的构建环境的任何方法调用jlink;e、 g.任意一种:maven插件、gradle插件、命令行实用程序、jpackage
实用程序或jpackage构建工具插件等。
相关答案
这个想法不是我的,是在这里提出的:
如果需要更多信息,下面将提供完整的教程示例。
解决方案说明
这个答案很长,因为它试图提供一个完整的例子和额外的上下文建议。它可以更简洁。它的风格更接近于教程或博客风格的文章,而不是答案。希望长度不会令人生畏,并且很容易复制结果。
我对这个很好奇,所以我想试试。令我惊讶的是,我能让它工作。所以我在这里记录了如何复制它。
关键是“哦,上帝蜘蛛”在评论中建议使用“warp”工具进行包装,并结合其他建议与jlink接口的评论。
我试着使用Maven构建工具尽可能多地完成这些工作,所以这个解决方案就是针对这一点的。如果愿意,您可以将解决方案调整到另一个工具链。
解决方案示例使用FXML构建JavaFX应用程序。如果不包含FXML,示例可能会更简单、更小,但我认为展示资源如何与此解决方案一起工作很重要,这就是为什么包含FXML的原因。
局限性
>
它只适用于依赖于具有模块信息的Java模块的应用程序。java
定义。例如,除非它是完全模块化的,否则它不适用于Spring或SpringBoot应用程序。这是,直到Spring6或SpringBoot3(具有完整的Java平台模块支持)发布。
高级步骤
>
将应用程序构建为Java平台模块化应用程序。
链接应用程序以创建带有启动脚本的运行时映像。
将带有启动脚本的运行时映像转换为exe。
warp packer
工具,可通过maven exec插件执行
程序
tools\warp packer。exe
mvn-package
)
target/hellowarp.exe
)对其进行测试
无需安装应用程序,无需提取或解压缩任何归档文件,无需安装Java运行时,也无需其他安装。只需将exe文件复制到windows计算机(例如,单击web上的下载链接或从邮件附件中复制exe),然后双击exe文件即可立即运行应用程序。
文件树
C:\dev\hellowarp>tree /a /f . Folder PATH listing for volume Local Disk Volume serial number is 00000086 C034:A84E C:\DEV\HELLOWARP | pom.xml | +---src | \---main | +---java | | | module-info.java | | | | | \---com | | \---example | | \---hellowarp | | HelloController.java | | HelloWarp.java | | | \---resources | \---com | \---example | \---hellowarp | hello-view.fxml | \---tools warp-packer.exe
获取和安装翘曲
在项目的根目录中创建一个新目录\tools
。
下载Warp从:
并将扭曲可执行文件(重命名)复制到以下位置:
\tools\warp-packer.exe
文件夹
pom.xml
Maven项目。
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>hellowarp</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>17</java.version>
<javafx.version>17.0.1</javafx.version>
</properties>
<dependencies>
<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>
</dependencies>
<build>
<plugins>
<!--compile-->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
</configuration>
</plugin>
<!--create linked image-->
<plugin>
<groupId>org.openjfx</groupId>
<artifactId>javafx-maven-plugin</artifactId>
<version>0.0.8</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>jlink</goal>
</goals>
</execution>
</executions>
<configuration>
<mainClass>com.example.hellowarp/com.example.hellowarp.HelloWarp</mainClass>
<compress>2</compress>
<noManPages>true</noManPages>
<noHeaderFiles>true</noHeaderFiles>
<stripDebug>true</stripDebug>
<launcher>${project.artifactId}</launcher>
</configuration>
</plugin>
<!--package image as an exe-->
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>3.0.0</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>exec</goal>
</goals>
</execution>
</executions>
<configuration>
<!-- obtain warp-packer.exe from: "https://github.com/dgiagio/warp/releases/download/v0.3.0/windows-x64.warp-packer.exe" -->
<executable>${project.basedir}\tools\warp-packer.exe</executable>
<arguments>
<argument>--arch</argument>
<argument>windows-x64</argument>
<argument>--input_dir</argument>
<argument>${project.build.directory}\image</argument>
<argument>--exec</argument>
<argument>bin\${project.artifactId}.bat</argument>
<argument>--output</argument>
<argument>${project.build.directory}\${project.artifactId}.exe</argument>
</arguments>
</configuration>
</plugin>
</plugins>
</build>
</project>
模块信息。JAVA
应用程序的Java平台模块定义。
module com.example.hellowarp {
requires javafx.controls;
requires javafx.fxml;
opens com.example.hellowarp to javafx.fxml;
exports com.example.hellowarp;
}
你好。JAVA
JavaFX应用程序。
package com.example.hellowarp;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.stage.Stage;
import java.io.IOException;
public class HelloWarp extends Application {
@Override
public void start(Stage stage) throws IOException {
FXMLLoader fxmlLoader = new FXMLLoader(
HelloWarp.class.getResource(
"hello-view.fxml"
)
);
Scene scene = new Scene(fxmlLoader.load());
stage.setTitle("Hello!");
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch();
}
}
Hello控制器。JAVA
JavaFXML控制器类。
package com.example.hellowarp;
import javafx.fxml.FXML;
import javafx.scene.control.Label;
public class HelloController {
@FXML
private Label welcomeText;
@FXML
protected void onHelloButtonClick() {
welcomeText.setText("Welcome to my JavaFX Application!");
}
}
你好。fxml
用户界面视图定义文件。
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.VBox?>
<?import javafx.scene.control.Button?>
<VBox alignment="CENTER" spacing="20.0" prefWidth="250" xmlns:fx="http://javafx.com/fxml"
fx:controller="com.example.hellowarp.HelloController">
<padding>
<Insets bottom="20.0" left="20.0" right="20.0" top="20.0"/>
</padding>
<Label fx:id="welcomeText"/>
<Button text="Hello!" onAction="#onHelloButtonClick"/>
</VBox>
运行hellowarp的屏幕截图。exe
应用程序
还有FAQ部分只是提供上下文信息。如果您已经知道此信息,或者您不需要它,您可以忽略此部分。
这是“胖罐子”的另一种分发方法吗?
是的,我想是的。
这适合做什么?
分布在您知道用户正在运行Windows的环境中的小规模应用程序。
我还可以将我的应用打包为MSI安装程序吗?
对我使用akman jpackage maven插件做到了这一点,它工作得很好。为了限制规模和范围,我不会在本回答中记录这一点。
使用“git repo”、“fat jar”、exe、打包安装程序或“压缩”映像是否更好?
这取决于你在做什么。
如果您的目标是其他开发人员,请在github上设置一个帐户,将您的项目放在那里,并提供一个maven或gradle构建文件,供开发人员在其环境中从源代码构建应用程序。只需将应用程序打包为标准jar文件(无fat jar)就可以了。您创建的任何jar都可以部署到maven central。使用模块信息。jar的java,以便通过jlink将其链接到打包的应用程序中。
如果是学校的项目。这取决于学校的录取偏好。也许他们只是想要git中的源代码,这就是您所需要的。或者,您可以创建一个(精简的)jar文件(或者一个包含jar及其依赖项的zip),您可以提供该文件,因为标准学校系统已经安装了所有相关的Java/JavaFX软件。
或者它可能是一个已知的操作系统环境,例如Windows、Mac或Linux,您可以使用jpackage
为其中一个(或两个)环境构建一个可安装的软件包。
或者,如果只是windows,这种打包为分发的“exe”的解决方案可能会很好地工作。
JavaFX开发不支持“胖罐子”配置。我不推荐它。你可以让它工作(目前),有时会很方便,但是你需要决定这样做所涉及的权衡是否值得。
如果您正在构建一个商业或流行的开源桌面产品,请创建打包的安装程序,使用一个工具,如jpack
(或一个商业或开源替代品),以适合您的目标平台的格式(例如msi或exe for windows,rpm和deb为linux,dmg为mac)。您可以选择将这些打包格式部署到Windows或Mac应用程序商店或Linuxyum/apt存储库。
如果是移动部署,请使用Glion mobile。
我可以使用ApacheJLinkMaven插件而不是OpenJFXMaven插件吗。
此时,OpenJFX JavaFX Maven插件或akman jpackage Maven插件将生成正确的图像。
ApacheJLinkMaven插件目前将失败(使用JavaFX17.0.1和ApacheJLink插件3.1.0)。
当我尝试使用ApacheJLinkMaven插件时,它被JavaFX平台模块定义弄糊涂了。ApacheJLink插件开始使用奇怪的幻影模块名称,如javafx。graphicsEmpty
将其视为自动模块并传递给jlink,因此jlink拒绝将其链接。我找不到解决这个问题的办法。
当我双击exe时,除了我的应用程序窗口外,标题栏中还有一个空白窗口,其名称为exe
。
对这取决于应用程序,它可能是一个小麻烦,也可能是一个阻碍。
双击时显示黑屏就是这个解决方案的工作方式。
我还没有做过很多调查。您可以查看此处提供的信息(其中讨论了在MS windows中隐藏或最小化应用程序启动程序窗口的各种方法),看看它是否有助于您:
如果不是双击应用程序,而是通过在命令控制台中键入exe名称来运行应用程序,则没有额外的屏幕,因为已经有一个您正在键入的现有控制台。
我可以使用此技术为其他操作系统创建单文件可执行文件吗?
是的,我想是的。
目前,我还没有尝试将此解决方案用于除了Windows可执行文件以外的任何东西。
warp packer
能够为各种操作系统生成可执行文件。
要为非windows机器进行打包,您需要将目标操作系统的相应jlink
映像输出输入到warp packer,然后运行相应的warp packer实用程序(我相信是在目标操作系统上)以生成单个可执行文件,以便在该目标操作系统上执行。
如果感兴趣,请参阅warp packer和jlink文档。
生成的可执行文件的大小是多少?
对于示例应用程序,我生成的应用程序可执行文件大小为34 MB。
启动时间是什么时候?
我没有测量它,但是启动时间(双击exe后显示应用程序图形用户界面窗口的时间)似乎大约是一秒钟。
我可以为非模块化Java项目创建exe吗?
可能是的,但这超出了我准备在这里讨论的范围,并且方法与这里描述的不同。
在没有显式线程创建的情况下,java程序在操作方面表现如何?整个程序是在一个进程中执行的吗?还是隐式地创建线程?这个问题在我学习线程以及线程如何在GUI交互中有用的时候出现,因为它允许用户与GUI交互,同时允许程序在后台执行操作。那么这是否意味着一个简单的java程序运行一个进程,在不使用线程的情况下顺序执行每一行?
问题内容: 我有一个我希望可以被任何用户轻松安装的程序,我认为创建本地安装程序是必经之路。我使用了Netbeans 8.0的功能(“项目”属性>“启用本机打包”和“打包为”)。我能够创建一个有效的本机安装程序。安装后,我具有以下文件树: 从Project.jar执行该程序。但是,当我尝试启动Project.exe时,在 没有任何详细信息 的窗口弹出窗口中收到以下错误消息: 为了确定问题的根源,我使
null 附注。不幸的是,“portableapps.com”解决方案是不可接受的。
问题内容: 我想在Windows中将Java程序作为exe运行。Windows盒根本不安装Java … 那么,还有其他方法可以将Java程序转换为exe,从而消除对JRE的依赖吗? 问题答案: 为此,您可以使用Excelsior JET编译器。 看到 http://www.excelsiorjet.com/了解更多信息。
问题内容: 有人建议可以怎一个JAVA程序运行不写一个主要方法.. 例如: 不使用类中的公共静态void main(String arg []),如何在控制台上打印以上行。 问题答案: 直到JDK6,您都可以使用静态初始化程序块来打印消息。这样,一旦您的班级被加载,消息就会被打印出来。然后,技巧就变成了使用另一个程序来加载您的类。 当然,您可以按如下方式运行程序,您将看到消息;但是,该命令也会失败
我想参加一场比赛。Java一直是我编写游戏的工具,所以很自然我会想在这个游戏中使用它。问题是,它不能需要其他软件。我相信这包括Java。那么,有没有办法在某种exe文件中包含java?或者以其他方式包括它?资产不必包含在内,但总体大小必须小于1GB,因此我需要足够的空间来存放实际的游戏和资产。