49

I'm setting up a maven project, that is going to use JavaFX. Since I've heard JavaFX does not come with all versions of Java, I downloaded and put the jfxrt.jar file in a lib directory in my project.

1) How do I specify that the dependency (ie., JavaFX) should not be downloaded, but which is located in lib?

2) Does this then mean the project can be built on any machine with JDK (and not necessary JDK 1.7 - update 9+) ?

4

1 回答 1

76

最新 JavaFX 版本的 2019 年更新

从 Java 11 开始,JavaFX 已与 JDK 分离,因此 JavaFX 库不再自动与 JDK 安装捆绑在一起(例如在 Oracle JDK 8 发行版中)。相反,JavaFX 系统现在被设计为一组独立于 JDK 的独立库,可以通过 Maven 等工具从存储库下载这些库,供您的应用程序使用。

openjfx.io 有一个关于在 Maven 中使用 JavaFX 11+ 的简短教程:

本教程建议使用OpenJFX JavaFX Maven 插件,并为“hello, world”风格的应用程序提供以下示例 maven pom.xml 项目文件。

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>org.openjfx</groupId>
  <artifactId>hellofx</artifactId>
  <packaging>jar</packaging>
  <version>1.0-SNAPSHOT</version>
  <name>demo</name>
  <url>http://maven.apache.org</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>

  <dependencies>
    <dependency>
      <groupId>org.openjfx</groupId>
      <artifactId>javafx-controls</artifactId>
      <version>12.0.1</version>
    </dependency>
  </dependencies>
  <build>
    <plugins>
      <plugin>
        <groupId>org.openjfx</groupId>
        <artifactId>javafx-maven-plugin</artifactId>
        <version>0.0.2</version>
        <configuration>
          <mainClass>HelloFX</mainClass>
        </configuration>
      </plugin>
    </plugins>
  </build>
</project>

请注意,用于 Java 11+的org.openjfx JavaFX maven 插件与用于 Java 8 和 9 的com.zenjava JavaFX maven 插件不同,因此请使用适合您的 Java 版本的插件。

建议的方法

使用 Maven 构建 JavaFX 应用程序:

  1. 使用带有 Java 8 和 9 AND/OR的com.zenjava maven JavaFX 插件
  2. 使用 Java 8 或 9 并且不为 JavaFX 指定任何类型的 Maven 依赖项或
  3. 在Java 11+ 中使用org.openjfx maven JavaFX 插件。

与 Java 7 不同,Java 8 没有必要将 JavaFX 设置为 maven 依赖项,因为 JavaFX 位于标准 Java 运行时类路径上(类似于今天的 Swing 方式)。

观点

我认为您将jfxrt.jar文件放在项目lib目录中的问题的方法是有缺陷的。

它有缺陷的原因是:

  1. JavaFX 还包含本机库,因此您也需要包含它们(在jfxrt.jar能够找到它们的位置)。
  2. 给定版本的 JavaFX 将仅经过认证可针对其随附的 JDK 版本进行操作,因此您放置在项目lib目录中的 JavaFX 运行时可能不适用于更高版本的 JDK,例如 JDK 8。
  3. JDK 的未来版本(例如 JDK 8)将在 JDK 的默认类路径中包含 JavaFX,因此您可能会与放置在lib目录中的版本发生冲突。

总之,JavaFX 应该被视为 Java 运行时系统的一部分,而不是项目库。

JavaFX 系统依赖示例

如果您必须使用 Java 7 并且不想使用 JavaFX maven 插件,那么您可以采用不太推荐的方法:

此示例仅为 Java 7 提供,Java 8 不需要(并且不会按原样工作)。Java 8 将 jfxrt.jar 放在 ${java.home}/lib/ext/jfxrt.jar 中,即在默认的 Java 运行时类路径上,使 Java 8 的系统依赖关系无关紧要。

<dependency>
  <groupId>javafx</groupId>
  <artifactId>jfxrt</artifactId>
  <version>${java.version}</version>
  <scope>system</scope>
  <systemPath>${java.home}/lib/jfxrt.jar</systemPath>
</dependency>

如果您使用这样的系统依赖项打包您的应用程序,那么您需要为您的用户编写一些执行指令,以便他们在 Java 7 上运行您的应用程序时可以将 jfxrt.jar 添加到运行时类路径。这是一个非常好的不使用这种方法的理由。

如果您选择使用 maven 系统依赖方法,您可能还希望使用 maven antrun 插件来嵌入对JavaFX ant 任务的调用,如本示例中所示。您可能还想使用maven enforcer 插件来确保您的应用程序至少是根据最低要求的 Java 版本构建的,其中包含您的应用程序工作所需的 JavaFX 版本。

于 2013-03-07T23:36:11.133 回答