7

我想从同一源代码树和同一台机器上构建一个 .msi、.deb 和 .pkg。

Java9+ 的可分发运行时不再可下载,因此像 launch4j+nsis 这样的完美解决方案不再有效。

javapackager 已被 Oracle 弃用。

OpenJDK 的 jpackager 不能(也永远不会)为不同的构建项目交叉编译,它甚至还不是真正的产品。

有没有办法从同一台机器上为 win/linux/macos 构建安装程序?

“一次编译,到处运行”的承诺真的死了吗?

我有一个遗留的 Java 应用程序现在处于不确定状态,因为 MacOS java8 不支持需要 java9+ 的 java.awt.desktop

4

3 回答 3

3

在 linux 上创建 Windows MyApp.exe 和 MyApp-setup.exe:

我根本不需要jpackage,只有jlink,launch4jnsis:

  • 在本机使用jlink一次来创建运行时并将
    结果 tar 以在其他机器上使用。
  • launch4j可以指示使用该运行时,并且nsis可以被
    告知在安装时复制整个运行时。

MyApp.app在 Linux 上创建 MacOS :

  • 用于jlink创建可重复使用的 tar 文件Contents/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.plistContents/app/MyApp.cfg归档jpackage
  • Contents/app用我的Contents/Resourcesjar文件和其他资源填写

在 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

或者,从迁移nsisinstall4j

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 的重点是可移植性和架构独立性。

于 2020-07-05T04:35:59.840 回答
3

我从 Java 9 开始使用,jlinkjpackage使用不同的 docker 映像和虚拟机组成的跨平台设置,我可以在其中构建运行时和安装程序(MSI、DEB/RPM 和 DMG/PKG)在我的目标平台上主机系统。

对于 Mac,您可以使用 KVM 映像,如果您没有 Apple 硬件,您可以通过 ssh 发出命令。

对于 Windows,使用 Linux docker 容器,包含 wine、Windows 的 OpenJDK、Visual Studio 构建工具、WIX 和 CMake 来执行运行时映像的构建和自定义的 MSI 安装程序(因为javapackage版本太简单了)

于 2020-09-01T11:58:05.153 回答
3

你的问题的答案并不简短。但我会尽量简短并指出所有相关信息。

简短的回答是:你可以做到这一点。

更长的答案是:您仍然必须从该目标环境中为每个目标环境构建一个运行时,但您只需执行一次。然后,您可以保存该运行时并重用它,以便在单个环境中使用最新的 Java jar/代码自动构建安装程序。例如,用于jlink构建运行时映像并jpackage为 Windows、Linux 和 macOS(在这些各自的系统上)构建应用程序映像,然后将这些应用程序映像复制到 macOS 并nsis为每个平台构建安装程序(或您选择的安装程序构建器)从 macOS 内部。

当您更新代码并重新编译时,您只需将新 jar 复制到预构建的应用程序映像中即可。您还必须复制所有依赖项,但这对于任何安装程序都是必需的。在由它构建的运行时中有一个配置文件,jpackage其中包含选项、类路径等,您可以更改它们而无需重新构建运行时。

  1. 创建一个可运行的程序,就像这样简单
    package com.example;

    public class Greeter {
        public static void main(String[] args) {
            System.out.println("Hi, I'm the greeter. Welcome.");
        }
    }
  1. 编译程序并放入 jar 中(greeter.jar在本例中调用它并放置在构建目录中,target在本例中调用)
  2. 运行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
  1. 运行jpackage以构建适合在安装程序中打包的应用程序映像。这使用来自 JDK14 early access 的 jpackage(在撰写本文时唯一的 JDK 版本jpackage)。命令行选项—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
  1. 运行应用程序.\Greeter\Greeter.exe

生成的应用程序映像(在app-image目录中)可用于使用您最喜欢的安装构建器(我使用 NSIS)构建安装程序。您可以在任何平台上执行此操作。此外,当您更新程序时,您只需将新 jar 复制到应用程序映像中。无需重新构建应用映像或运行时。jar 的这个副本可以在任何平台上进行,并且不需要运行 Windows 来为您的应用程序的新版本构建新的安装程序。

如果您的应用程序具有 jar 依赖项(例如来自 Maven 中心),您需要将这些 jar 复制到Greeter/app目录并app.classpathGreeter/app/Greeter.cfg文件中更新。同样,所有这些都可以在任何平台上完成,无需启动目标平台(在我的例子中是 Windows)。

此外,jpackage它是官方支持的工具,但仅在 EA JDK 14 中可用(我写的是 2020 年 2 月)。JDK 14 可以下载并jpackage与其他版本的 JDK(如 JDK 11 LTS)一起使用。

请参阅https://blogs.oracle.com/jtc/a-brief-example-using-the-early-access-jpackage-utility

JEPjpackage已被标记为“Closed/Delivered”,表明该工具已经成熟,正在等待 JDK 14 发布:https ://openjdk.java.net/jeps/343

GitHub 上有一个示例项目,其中有很多关于如何运行的有用命令行示例jlinkjpackagehttps: //github.com/jtconnors/SocketClientFX 虽然这个项目使用过时的命令选项。您可以运行jpackage --help以获取新选项。

有用的链接:

JDK 14(提前访问至 2020 年 3 月 17 日):http: //jdk.java.net/14/

解释 jlink 的非模块化用法:https ://medium.com/azulsystems/using-jlink-to-build-java-runtimes-for-non-modular-applications-9568c5e70ef4

jlink 手册:https ://docs.oracle.com/javase/9​​/tools/jlink.htm#JSWOR-GUID-CECAC52B-CFEE-46CB-8166-F17A8E9280E9

jpackage - 运行-help选项以获得良好的参考信息

于 2020-02-26T22:15:04.437 回答