首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >有没有办法为同一平台上的多个目标构建java应用程序的安装程序?

有没有办法为同一平台上的多个目标构建java应用程序的安装程序?
EN

Stack Overflow用户
提问于 2019-11-03 06:36:55
回答 3查看 1K关注 0票数 7

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

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

javapackager已经被Oracle抛弃了。

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

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

“编译一次,到处运行”的承诺真的已经消亡了吗?

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

EN

回答 3

Stack Overflow用户

发布于 2020-02-27 06:15:04

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

简单的回答是:你可以做到。

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

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

  1. 创建一个可运行的程序,就像

一样简单

代码语言:javascript
运行
复制
    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以构建运行时。以下命令使用JDK11中的jlink,并将结果放在名为runtime的目录中。这个示例包括模块路径上的所有模块,但是您可以使用jdeps来获取所需的模块。如果您不想在项目发展时重新构建此运行时,并依赖于更多的Java运行时,我建议包含所有模块。更不用说对JRE.

的传递依赖了

代码语言:javascript
运行
复制
    > 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以构建适合在安装程序中打包的应用程序映像。这使用了JDK (在撰写本文时唯一具有jpackage的JDK14版本)中的jpackage。命令行选项—win-console仅适用于Windows,并且只有在程序使用stdin/stdout (控制台)执行某些操作时才是必需的。我们的示例写入控制台,所以我们需要它。在运行应用程序时,此参数有时可能会打开控制台窗口,因此如果您使用的是纯基于windows (gui)的application.

,请删除此参数。

代码语言:javascript
运行
复制
    > 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)构建安装程序。您可以在任何平台上执行此操作。此外,当您更新您的程序时,您只需将新的jars复制到应用程序镜像中。不需要重新构建应用程序映像或运行时。这个jars副本可以在任何平台上运行,并且不需要运行Windows来为应用程序的新版本构建新的安装程序。

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

此外,jpackage是一个官方支持的工具,但仅在EA JDK14中可用(我写这篇文章时是2020年2月)。JDK14可以下载,jpackage可以与其他版本的JDK (如JDK11LTS)一起使用。

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

JEP for jpackage已经被标记为“已关闭/已交付”,这表明该工具已经成熟,只需等待JDK14发布:https://openjdk.java.net/jeps/343

GitHub上有一个示例项目,其中包含许多关于如何运行jlinkjpackage的有用命令行示例:https://github.com/jtconnors/SocketClientFX,尽管该项目使用的命令选项已过时。您可以运行jpackage --help来获取新的选项。

有用链接:

JDK14(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选项运行,以获取良好的参考信息

票数 2
EN

Stack Overflow用户

发布于 2020-09-01 19:58:05

从Java9开始,我就开始使用jlinkjpackage,这是一个由不同的docker镜像和虚拟机组成的跨平台安装程序,我可以在我的主机系统中的目标平台上构建运行时和安装程序(MSI、DEB/RPM和DMG/PKG)。

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

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

票数 2
EN

Stack Overflow用户

发布于 2020-07-05 12:36:00

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

我根本不需要jpackage,只需要jlinklaunch4jnsis

  • 本机使用一次jlink来创建运行时,并将

可以指示在其他machines.

  • launch4j上使用的结果使用该运行时,并且nsis可以

被告知在安装时复制整个运行时。

Creating a MacOS linux on linux:

  • 使用jlink创建一个可重复使用的压缩文件,以便在生成的jpackage中重新创建Contents/runtime/Contents/Home (类似于上面的windows )
  • 拷贝

Contents/runtime/Contents/Info.plist

Contents/runtime/Contents/MacOS/libjli.dylib

  • Copy在change.

  • Create中生成了Contents/MacOS/libapplauncher.dyn存根和存根,希望他们永远不需要从模板中使用Contents/Info.plistContents/app/MyApp.cfg文件,使用jpackage生成的存根作为Contents/app中的存根,Contents/Resources与我的jar文件和其他资源

<代码>F246

在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的全部要点是可移植性和架构独立性,这种多平台交叉编译工具在任何地方都不存在,这是一种荒谬的想法。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58675893

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档