gpt4 book ai didi

java - 使 ScalaFx 在 JDK 8 和 11 上都能工作

转载 作者:行者123 更新时间:2023-12-01 19:55:06 26 4
gpt4 key购买 nike

令我沮丧的是,我意识到 my open source ScalaFX application不与 JDK 11 一起运行。该应用程序是使用 JDK 8 开发的。我已经阅读了有关 JFX 模块的信息,我可以看到存在专用于 JDK 11 和更新版本的 ScalaFX 版本( ScalaFX 12 )。我理解它的方式并没有达到我想要的 - 我必须为 JDK 8 和 JDK 11 构建不同版本的应用程序。

有没有办法让单个 ScalaFX 应用程序同时在 JDK 8 和 11 上运行?

最佳答案

更新 :我已经简化和扩展了我的原始答案。

为了解决您的主要问题,我认为应该可以编写一个针对 JavaFX 8 和 JavaFX 9+ 的单个 ScalaFX 8 应用程序,前提是您坚持使用前者定义的 API。因此,我建议使用带有 ScalaFX/JavaFX 8 的 Java 8 JDK 编译您的应用程序。如果您使用 Java 9+ JDK,或者针对高于 8 的任何 ScalaFX 版本进行构建,那么您将无法运行您的应用程序具有 Java/JavaFX 8 运行时的应用程序。

(如果您想支持 ScalaFX/JavaFX 的新功能,那么您别无选择,只能以它们出现的特定版本为目标,如果您仍然需要支持旧版本,这可能需要您生成多个版本的应用程序。由于您已经声明这不是您的目标,我在这里针对的是 ScalaFX/JavaFX 8。)

请注意,Java 版本 8 和 11 是长期支持 (LTS) 版本; Java 版本 9、10 和 12 不是,而且更加前沿。

正如您已经知道的,在 Java 9 中引入 Jigsaw 模块之后,Java 8 和后续 Java 版本之间存在根本差异。Scala 对模块的支持仍然非常原始,目前或多或少假装它们不存在,这在这种情况下实际上有帮助。

需要解决的主要问题是在运行应用程序时配置 Java 虚拟机 (JVM)。

顺便提一下,请注意,我使用术语 JavaFX 来包含 OpenJFX ,这是 JavaFX 的开源版本。

使用 JavaFX 8 运行应用程序时,将有一个名为 jfxrt.jar 的 JAR 文件。 ,您需要做的就是确保您的类路径中有该文件。这基本上与您的应用程序一直具有的要求相同,因此您应该在这里做得很好。顺便说一句,JavaFX 8 应该仍然可以与 Java 9+ 一起正常工作,因为 Java 9+ 需要保持与旧的非模块化库的兼容性。

但是,当使用 JavaFX 9+ 运行您的应用程序时,事情会变得更有趣...

首先,根据经验,如果您使用的是 JavaFX 版本 X(其中 X 是高于 8 的某个版本),您通常还必须使用版本等于或高于 X 的 JVM。也就是说,您应该例如,可以使用 JVM 版本 11 运行 JavaFX 9。但是,您通常不能期望将 JavaFX 11 与 JVM 版本 9 一起使用。

虽然 JavaFX 8 有一个包含整个库的 JAR 文件,但 9+ 版本被打包成许多单独的模块,每个模块都有自己的 JAR 文件:

  • javafx-base
  • javafx-controls
  • javafx-fxml
  • javafx-graphics
  • javafx-media
  • javafx-swing
  • javafx-web .

  • 如果你不需要,比如 javafx-swing 中定义的元素,那么就可以忽略对应的JAR文件了。但是,为了安全起见,您可能需要要求所有这些,这就是我在这里要做的。

    您需要告诉 JVM 这些是模块,并在应用程序运行时加载它们。

    例如,假设您已将 JavaFX 11 安装到名为 C:\JavaFX11 的目录中。在您的机器上,这样库的 JAR 文件位于 C:\JavaFX11\lib .假设我有一个环境变量, JAVAFX_HOME标识后一个目录。您现在需要在运行应用程序时将以下参数传递给 JVM:
     --module-path %JAVAFX_HOME%
    --add-modules javafx.base,javafx.controls,javafx.fxml,javafx.graphics,javafx.media,javafx.swing,javafx.web

    这些选项仅对版本 9 或更高版本的 JVM 有效。 (显然,这也适用于 Windows;您需要为其他平台做类似的事情。)

    如果您不这样做,那么您可能会看到一个错误,说明 Error: JavaFX runtime components are missing, and are required to run this application . (如果您看到不同的东西,您能否更新您的问题以显示在 JDK 11 下运行 ScalaFX 8 应用程序的结果?)

    当然,诀窍是让运行应用程序的脚本检测安装的 JavaFX 版本。如果您要求用户定义 JAVAFX_HOME 可能会有所帮助指定 JavaFX 库安装位置的环境变量。如果它包含一个名为 jfxrt.jar 的文件,那么您使用的是版本 8,否则使用版本 9+。在后一种情况下,您可能还想在提供其他参数之前验证您使用的是 9+ 版本的 JVM。

    如果您违反任何打包为模块的库中定义的任何模块限制,仍有一些潜在的香蕉皮(可能导致运行时错误)。如果您坚持已发布的 JavaFX 8 API 规范,并且不尝试访问私有(private)实现类,那么您应该会很好。

    更新 2 : 进一步评论。

    I am not interested in any newer features, my only goal is to make old Java 8 application runnable with new JDKs, including JDK 11 and 12. If I would like to distribute JFX 8 (a single jar jfxrt.jar you have mentioned), how do I get it? I found maven artifacts only for JFX 11 and newer, downloads at gluonhq.com/products/javafx also start with 11)



    如您所知,JavaFX 8 作为 Oracle Java 8 运行时环境 (RTE) 的一部分捆绑在一起。无论如何,这个 Oracle 版本的 JavaFX 是专有的,将它与您的产品一起分发可能是不明智的。

    此外,您可能知道,OpenJDK 8 RTE 版本不捆绑 JavaFX,让用户自行安装 OpenJFX 8。在后一种情况下,此版本的任何存储库中都没有可用的工件,因为直到模块化才有可能打包 JavaFX。

    我的理解是 Gluon 最近才开始支持 JavaFX(作为 OpenJFX),提供独立下载,并在 Maven Central Repository 上提供打包的工件。 ,仅从 JavaFX 11 开始。在他们加紧之前,这是 Oracle 控制的责任 OpenJFX project .后者仍然托管 official Mercurial-based code base ,但已将其大部分链接(包括下载链接)更新到 Gluon 站点。

    从谷歌搜索“OpenJFX 8 下载”似乎没有太多可用的选项,但正在构建 your own version from the sources是一种可能性。使用类似 wayback machine 的东西是另一个。如果您在 Linux 上运行,许多发行版仍会在其存储库中提供 OpenJFX 8 版本。

    也许您可以向 Gluon 报告缺少 JavaFX 8 运行时,看看他们是否准备发布一个?

    然而,还有一个更大的问题正在酝酿:您面临的主要问题是 JavaFX 不是一个纯 Java 库。它包含许多从 JavaFX JAR 文件引用的特定于平台的库。只需捆绑您自己的版本 jfxrt.jar将无法工作,因为每个平台的基础库都将丢失。

    即使您可以克服这个问题,您也需要为每个受支持的平台(Windows 64 位、Windows 32 位、MacOs 等)提供不同的版本,并带有适当的 OpenJFX 捆绑版本。

    您可能需要考虑放弃对 JavaFX 8 的支持,因为您随后可以将平台相关的库依赖项添加到您的应用程序构建中,并使用 SBT 插件,例如 sbt-native-packager将您的 JavaFX 依赖项捆绑到特定于平台的安装包中。

    如果您仍然需要支持 JavaFX 8,您目前别无选择,只能依靠用户自己提供 JavaFX。

    I have tried a JDK 8 directory containing jfxrt (which is Java\jdk1.8.0_161\jre\lib\ext for me) to the classpath of the application running under JDK 11 and the application was unable to start, with the exception "java.lang.RuntimeException: Exception in Application start method" with additonal information "Caused by: java.lang.NoClassDefFoundError: sun/misc/SharedSecrets"



    如果没有看到您的代码、它是如何运行的以及应用程序的完整输出,就很难确切地说出导致此问题的原因。您能否更新您的问题以包含该信息?

    关于java - 使 ScalaFx 在 JDK 8 和 11 上都能工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57757132/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com