我使用jlink创建了一个Java应用程序运行时镜像。我希望能够将软件作为可执行文件传送到不同的平台(最好是通过在一个平台上进行构建,如交叉编译)。
理想情况下,这将是一个单个的应用程序文件,用户可以双击启动,而无需安装任何东西。
如何实现这一目标?
我使用jlink创建了一个Java应用程序运行时镜像。我希望能够将软件作为可执行文件传送到不同的平台(最好是通过在一个平台上进行构建,如交叉编译)。
理想情况下,这将是一个单个的应用程序文件,用户可以双击启动,而无需安装任何东西。
如何实现这一目标?
Launch4J(Windows)
Oracle Docs(MacOS)
Discourse(Linux)
Quarkus(本地可执行文件,无需安装程序)
Warp Packer(自解压可执行文件,无需安装程序)
最初的回答已翻译完毕,以上是需要翻译的内容。Substrate VM是一个框架,允许在封闭世界假设下预先编译Java应用程序为可执行映像或共享对象(ELF-64或64位Mach-O)。
<plugins>
<plugin>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/lib</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<version>3.2.0</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<mainClass>${project.groupId}.${project.artifactId}.DemoCLI</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE xml>
<!--
Uses the JavaFX Ant Tasks to build native application bundles
(specific to the platform which it is built on).
See https://docs.oracle.com/javase/8/docs/technotes/guides/deploy/javafx_ant_tasks.html
These tasks are distributed with version 8 of the Oracle JDK,
Amazon Corretto JDK, RedHat JDK, probably others, though they
do not seem to be the OpenJDK on Debian Linux
-->
<project
name="fxwebclient" default="default" basedir="."
xmlns:fx="javafx:com.sun.javafx.tools.ant">
<!-- In Java 8, java.home is typically the JRE of a JDK -->
<property name="jdk.lib.dir" value="${java.home}/../lib" />
<!-- Where to build our app bundles -->
<property name="build.dist.dir" value="${basedir}/target/dist" />
<echo>Using Java from ${java.home}</echo>
<target name="default" depends="clean">
<!-- get the ant-jfx.jar from the JDK -->
<taskdef resource="com/sun/javafx/tools/ant/antlib.xml"
uri="javafx:com.sun.javafx.tools.ant"
classpath="${jdk.lib.dir}/ant-javafx.jar" />
<!-- Define our application entry point -->
<fx:application id="demo" name="demo"
mainClass="yourpackage.DemoCLI" />
<!-- Our jar and copied dependency jars (see pom.xml) -->
<fx:resources id="appRes">
<fx:fileset dir="${basedir}/target" includes="*.jar"/>
<fx:fileset dir="${basedir}/target/lib" includes="*.jar" />
</fx:resources>
<!-- Create app bundles [platform specific] -->
<fx:deploy nativeBundles="all"
outdir="${build.dist.dir}" outfile="DemoWebClient">
<fx:application refid="demo" />
<fx:resources refid="appRes" />
</fx:deploy>
</target>
<!-- clean up -->
<target name="clean">
<delete dir="${build.dist.dir}" includeEmptyDirs="true" />
<delete file="${basedir}/target/${ant.project.name}.jar" />
</target>
</project>
双击可在多个平台上运行可执行文件,需要先在操作系统中注册文件类型,或者已知文件类型以了解如何处理代码。
jlink将“所需模块及其传递依赖项”静态链接到输出中。
这个问题没有跨平台的解决方案。
将所有平台包含在一个单一文件中是不可能的(或者换句话说,不可行的),因为每种可执行文件类型(COFF、ELF...)都有不同的结构。您可以尝试使用通用批处理文件启动适当的可执行文件,但在Windows上,这将需要文本文件类型编码;从而污染剩余的二进制代码。
使用jlink 和 新的jmod文件格式将允许您将本地代码存储在Java容器中,从而允许在单个可执行映像中输入嵌入式本机JRE代码的入口点为单个预定义平台。
这个问题的另一面是安全性问题。由于嵌入式JRE不受安全更新的影响,黑客可能选择嵌入先前已知的有缺陷的JRE,从而向不知情的消费者暴露已纠正的漏洞。
反病毒程序的预期响应将是将所有未更新的嵌入式JRE标记为病毒。
jlink
允许在没有安装 Java 的情况下运行应用程序。这是它的主要目的。 - ZhekaKozlov
jlink
也可以做你想要的。 - ZhekaKozlov