我已经使用jlink为我的Java应用程序创建了一个运行时映像,我希望能够将我的应用程序作为可执行文件发布到不同的平台。
理想情况下,它将是一个文件,用户可以双击该文件并启动应用程序,而无需安装任何程序。
目前是否有个好方法?
答案 0 :(得分:2)
您可以制作一个用于安装JDK和应用程序的安装程序。通过使用诸如Launch4j之类的东西使该应用程序成为exe,对于Mac可执行文件,请遵循Oracle的本教程:Packaging a Java App for Distribution on a Mac,最后是For Linux
Minecraft使用这种方法,据我所知,没有其他方法。
如果要制作可移植的应用程序,使它“在任何地方运行一次”类型的应用程序,那么我建议尝试使用另一种编程语言,例如C#,它也需要.NET JVM,但已嵌入Windows系统中。
答案 1 :(得分:0)
双击以在多个平台上运行可执行文件,需要事先在操作系统中注册文件类型,或者需要现有文件类型才能知道如何处理代码。
jlink将“所需模块及其传递依赖项”静态链接到输出。
没有跨平台的解决方案。
将所有平台都包含在一个文件中是不可能的(或者用另一种方式,不可行),因为每种可执行文件类型(COFF,ELF ...)具有不同的结构。您可以尝试使用通用批处理文件来启动适当的可执行文件,但是在Windows上,这将需要文本文件类型编码。因此中毒了其余的二进制代码。
使用jlink 和新的jmod文件格式将允许您将本机代码存储在Java容器中,从而允许在单个可执行映像中将嵌入的本地JRE代码的入口点一个预定义的平台。
此问题的另一面是安全隐患。由于嵌入式JRE不受安全更新的影响,因此破解者可以选择嵌入以前已知的有缺陷的JRE,从而将更正的漏洞暴露给用户。
反病毒程序的预期响应是将所有未更新的嵌入式JRE标记为病毒。
答案 2 :(得分:0)
是的,从Java 8开始,使用javapackager工具或JavaFX Ant Tasks(实际上并不是特定于JavaFX的,而是Java 8 JDK提供的)有两种方法。
下面是一个使用Maven将应用程序打包为Jar,设置main-class和classpath属性以及将所有依赖项复制到文件夹中的示例。
<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>
这是用于打包独立应用程序(Windows的exe,OS X的.app和.dmg,Linux的.deb和.rpm)的Ant构建文件。
<?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>
答案 3 :(得分:-1)
另外,请查看SubstrateVM。这不是真正的Java,但是在某些情况下(例如简单的命令行应用程序)可能会为您提供帮助。
基板VM是允许提前(AOT)的框架 在封闭世界假设下将Java应用程序编译为 可执行映像或共享对象(ELF-64或64位Mach-O)。