3 回答
TA贡献1757条经验 获得超8个赞
我从 Java 9 开始就使用由不同的 docker 映像jlink
和jpackage
虚拟机组成的跨平台设置,我可以在我的目标平台上构建运行时和安装程序(MSI、DEB/RPM 和 DMG/PKG)主机系统。
对于 Mac,如果您没有 Apple 硬件,则可以使用 KVM 映像,以便通过 ssh 发出命令。
对于 Windows,使用 Linux docker 容器,其中包含 wine、Windows 的 OpenJDK、Visual Studio 构建工具、WIX 和 CMake 来执行运行时映像的构建以及自定义的 MSI 安装程序(因为版本太javapackage
简单)
TA贡献1773条经验 获得超3个赞
你的问题的答案并不短。但我会尽量简短并指出所有相关信息。
简短的回答是:你可以做到这一点。
更长的答案是:您仍然需要从目标环境中为每个目标环境构建运行时,但只需执行一次。然后,您可以保存该运行时并重用它,以便在单一环境中使用最新的 Java jar/代码自动构建安装程序。例如,用于jlink构建运行时映像并jpackage为 Windows、Linux 和 macOS(在这些各自的系统上)构建应用程序映像,然后将这些应用程序映像复制到 macOS 并nsis为每个平台构建安装程序(或您选择的安装程序生成器)从 macOS 内部。
当您更新代码并重新编译时,您只需将新的 jar 复制到预构建的应用程序映像中即可。您还必须复制所有依赖项,但这对于任何安装程序都是必要的。构建的运行时中有一个配置文件,jpackage其中包含选项、类路径等,您可以更改这些文件而无需重建运行时。
创建一个可运行的程序,就像这样简单
package com.example;
public class Greeter {
public static void main(String[] args) {
System.out.println("Hi, I'm the greeter. Welcome.");
}
}
编译程序并放入 jar 中(greeter.jar在本示例中调用它并放入构建目录中,target在本示例中调用)
运行jilnk以构建运行时。以下命令使用jlinkJDK11 中的内容并将结果放入名为 的目录中runtime。此示例包括模块路径上的所有模块,但您可以使用它jdeps来仅获取所需的模块。如果您不想在项目发展并依赖更多 Java 运行时时重新构建此运行时,我建议包括所有模块。更不用说对 JRE 的传递依赖了。
> set JLINK=C:\Program Files\Java\jdk-11.0.6\bin\jlink.exe
> "%JLINK%" --no-header-files --no-man-pages --compress=2 --strip-debug --add-modules ALL-MODULE-PATH --output runtime
运行jpackage以构建适合打包在安装程序中的应用程序映像。jpackage它使用 JDK14 早期访问版的 jpackage(撰写本文时唯一的 JDK 版本)。命令行选项—win-console仅适用于 Windows,并且仅当程序使用 stdin/stdout(控制台)执行某些操作时才需要。我们的示例写入控制台,所以我们需要这个。运行应用程序时,此参数有时可能会打开控制台窗口,因此如果您有纯基于 Windows (gui) 的应用程序,请将其删除。
> set JPKG=C:\Program Files\Java\jdk-14-ea\bin\jpackage.exe
> "%JPKG%" --type app-image -i target —win-console -n Greeter --main-class com.example.Greeter --main-jar greeter.jar --runtime-image runtime
运行应用程序.\Greeter\Greeter.exe
生成的应用程序映像(在app-image目录中)可用于使用您最喜欢的安装构建器(我使用 NSIS)构建安装程序。您可以在任何平台上执行此操作。此外,当您更新程序时,您只需将新的 jar 复制到应用程序映像中。无需重建应用程序映像或运行时。该 jar 副本可以在任何平台上进行,并且无需运行 Windows 即可为新版本的应用程序构建新的安装程序。
如果您的应用程序具有 jar 依赖项(例如来自 Maven 中心),则需要将这些 jar 复制到该Greeter/app目录并app.classpath在Greeter/app/Greeter.cfg文件中更新。同样,所有这些都可以在任何平台上完成,无需启动目标平台(在我的例子中是 Windows)。
此外,jpackage它是官方支持的工具,但仅在 EA JDK 14 中可用(我写的时候是 2020 年 2 月)。JDK 14 可以下载并jpackage与其他版本的 JDK(例如 JDK 11 LTS)一起使用。
TA贡献1826条经验 获得超6个赞
在 Linux 上创建 Windows MyApp.exe 和 MyApp-setup.exe:
jpackage
我根本不需要,只需要jlink
、launch4j
和nsis
:
在本机使用
jlink
一次来创建运行时并压缩
结果以供在其他计算机上使用。launch4j
可以指示使用该运行时,并且nsis
可以
指示在安装时复制整个运行时。
MyApp.app
在 Linux 上创建 MacOS :
用于
jlink
创建可重复用于重新创建的 tarfileContents/runtime/Contents/Home
(如上面的 Windows)复制
jpackage
生成的Contents/runtime/Contents/Info.plist
和Contents/runtime/Contents/MacOS/libjli.dylib
复制
jpackage
生成的Contents/MacOS/MyApp
存根并Contents/MacOS/libapplauncher.dyn
希望它们永远不必更改。使用生成的模板作为参考从模板创建并
Contents/Info.plist
归档Contents/app/MyApp.cfg
jpackage
填写我的jar文件和其他
Contents/app
资源Contents/Resources
在 Linux 上创建 pkg:
https://gist.github.com/msabramo/2a8e44eb6dcc3b89437d33649b0b1841
在 Linux 上创建 dmg:
https://askubuntu.com/questions/1117461/how-do-i-create-a-dmg-file-on-linux-ubuntu-for-macos
或者,从 迁移nsis
到install4j
https://www.ej-technologies.com/products/install4j/overview.html
理论上,一旦我在 Linux 上完成所有工作,我就可以将工作移植到 Darwin 和 cygwin (WSL 对我来说不适合 atm,将在最后工作)
概念证明在这里(linux、MacOS、cygwin):
https://github.com/nyetwurk/ecuxplot
考虑到 CI/CD 的兴起,而且 java 的重点是可移植性和架构独立性,这种多平台交叉编译工具在任何地方都不存在,这有点荒谬。
添加回答
举报