【问题标题】:What is the standard way to package/release a Java 17 application?打包/发布 Java 17 应用程序的标准方式是什么?
【发布时间】:2023-01-23 23:40:41
【问题描述】:

我有一个公开可用的 Java 8 桌面应用程序,其中包含我想更新到 Java 17 的 MSI 安装程序。

目前的用户体验是这样的:

  1. 用户下载 MSI 安装程序并运行它
  2. MSI 安装程序检查兼容的 Java 8 VM,如果不存在,提示用户从 http://java.com 安装一个。
  3. 用户启动application.exe,这是一个基本上运行java jar application.jar的垫片。

    我很难理解的是,用户应该在 Java 9+ 世界中安装什么。例如,如果我将用户发送到:https://www.oracle.com/java/technologies/downloads/,他们会收到下载 Java 开发工具包的欢迎,这对用户来说是一件令人困惑的事情(“这样对吗?我不想开发东西??”)。

    此外,当您登录 http://java.com 时,它说“如果您被要求下载 java,很可能是这个”,这意味着如果您发布应用程序,您应该使用 Java 8(并且忘记 OpenJDK pre version 的 JavaFX 灾难11,只使用 Orcale Java)...

    我的印象是,在 Java 9 之后,Jigsaw 的承诺是构建一个包含本机运行时和 jar 的包,所有这些都整齐地捆绑在一起,这样最终用户必须安装 JVM 的日子就结束了。但是在网上搜索时,我发现 Gradle 或 IntelliJ(或 Eclipse)对此没有支持,所以这看起来有点像白日梦?

    如果我想发布 Java 17 应用程序,用户是否需要安装 JDK?如果没有,我应该如何打包和发送我的应用程序?

【问题讨论】:

  • 这实际上取决于您的目标受众,但 IMO 最舒适的方法是在您的应用程序中安装/捆绑 JDK(或其中的一个子集)。例如,这就是 IntelliJ IDEA/Android Studio 所做的。通常,在许可方面,非 Oracle 发行版不那么麻烦。 This answer 可能有助于选择合适的。
  • 目标受众是 joe-and-jane-gamer。
  • @JoachimSauer 你有没有提到我在哪里可以看到这样做的常用方法?

标签: java release java-platform-module-system


【解决方案1】:

甲骨文的观点:

  • 不再有 JRE(来源:尝试查找 oracle 为您提供的高于版本 8 的 JRE - 它不存在)。
  • 相反,您编写您的应用程序模块,并使用 jlink 制作一个“tree shaken”JVM,这是一个 JVM,其中包含您作为基础使用的模块甚至不需要的所有内容。您为每个您有兴趣导出为独立安装程序的平台生成一个 JVM。
  • 然后您编写一个安装程序来安装 tree-shaken JVM,你的应用程序,某处。摇树 JVM 是不是注册为“系统 JVM”,事实上,PC 上安装了 JVM,您可以使用例如找到它。注册表项或通过查看已知位置(例如 C:Program FilesJavaSoft)已过时。您不这样做,JVM 仅适用于该应用程序,该应用程序知道在哪里可以找到它,而系统上的其他任何东西都不知道。每个基于 Java 的应用程序都有自己的 JVM 副本(无论是否摇树),只有它自己使用。
  • 作为“供应商”的您需要进行维护。如果你发布的 JVM 有一个巨大的安全漏洞并且被滥用,那是你没有更新它的错,而不是 oracle 的错。 Oracle 不运行 jusched.exe 或任何其他工具来确保它保持最新。

一个简单的替代方法是,您只需将拥有可以运行您的应用程序的 Java 运行时的责任转移到用户的肩上。告诉他们去下载 JDK(因为 JDK 可以运行 Java 应用程序,实际上比 JRE 更好),告诉他们确保它在 $PATH 或已知位置/告诉你在哪里可以找到它/设置JAVA_HOME,和他们负责保持更新。

其他厂商的观点:

  • 许多其他供应商确实为更现代的版本制作了 JRE。我不知道这些 JRE 是否附带 jusched.exe 或其他更新机制,以及如何(甚至如果) 这些 JRE 以您的应用程序/安装程序可以找出它们所在位置的方式注册它们的存在。你得调查一下。

无需真正对 JVM 进行 treeshake,您也可以随应用程序一起发布完整的 JDK。例如,如果您的安装程序最终这样做:

  • 将'program install root' ('root') 设置为C:Program FilesEmilysAwesomeGame
  • 将 JDK17 for windows x64 解压到 ROOTjdk
  • 将所有依赖项 jar 解压到 ROOTlib
  • 解压你的主应用到ROOTemilygame.jar
  • 创建一个运行%~dp0jdkhomeinjava -jar %~dp0emilygame.jar.BAT 文件,并且该 jar 有一个带有 Class-Path 条目的 MANIFEST,其中包含例如libjavafx.jar libsomeotherdep.jar,然后 .. 可以正常工作,并且用执行相同操作的 exe 替换该 bat 文件也可以正常工作(并且“在子目录中运送您自己的 JVM”是 launch4j 和类似工具具有的模型已经支持很久了)。

不使用 treeshaking 的缺点是 JDK 非常大,并且包含各种您不会使用的东西。但是,这只是节省磁盘空间的问题,非 treeshaken 的 JDK 不会运行得更慢,那些未使用的部分将永远不会被加载。

一个非常常见的“部署模型”是你提供一个 msi 和一个用于 windows-x86 的 exe 并告诉其他人自行负责安装 JDK 并为其他人(linux 用户,mac 用户,windows-aarch64 , ETC)。

【讨论】:

    【解决方案2】:

    这个问题被一遍又一遍地问。因此,在 SO 上对这个主题进行了广泛的讨论。请参阅:https://stackoverflow.com/tags/javafx/info 与您最相关的部分是关于“包装”的部分。

    【讨论】:

      猜你喜欢
      • 2021-12-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-05-19
      • 1970-01-01
      • 1970-01-01
      • 2010-09-09
      相关资源
      最近更新 更多