IntelliJ无法使用OpenJDK 11识别JavaFX 11


82

我无法让IntellJ识别JavaFX软件包。对于新的JavaFX项目和OpenJDK 11,在尝试构建项目时,IntelliJ无法识别JavaFX软件包。

我已经openjfx:javafx-base-11从Maven仓库导入了。

我看过其他问题,解决方案似乎范围从检查字节码是否处于正确级别(我的是),以及项目语言是否正确(我的是)。

谁有想法?

图片1

图片2

图片3

编辑:

错误:

在此处输入图片说明


您可以从终端尝试编译并运行吗?
淹死

您需要在您的module-info.java
Jacob G中

我认为您需要此工件:mvnrepository.com/artifact/org.openjfx/javafx/11基本对象不包含我想的所有内容。
乔恩·弗妮

@JornVernee,当我尝试得到一个错误时。我用它编辑了OP。
AlwaysNeedingHelp

1
谁告诉你这可能是错误的。您需要创建一个module-info.java在源文件夹中的文件,并明确要求为准JavaFX的模块,您使用的是:requires javafx.controls;requires javafx.graphics;,等
雅各布G.

Answers:


128

如注释中所述,《入门指南》是从Java 11和JavaFX 11开始的地方。

像在Java 11之前所做的那样工作的关键是要了解:

  • JavaFX 11不再是JDK的一部分
  • 您可以以不同的方式获得它,既可以使用SDK或常规依赖关系(Maven / Gradle)。
  • 即使您的项目不是模块化的,也需要将其包括在项目的模块路径中。

JavaFX项目

如果您在IntelliJ中创建常规JavaFX默认项目(没有Maven或Gradle),建议您从此处下载SDK 。请注意,也有jmods,但是对于非模块化项目,SDK是首选。

这些是运行默认项目的简单步骤:

  1. 创建一个JavaFX项目
  2. 设置JDK 11(指向本地Java 11版本)
  3. 将JavaFX 11 SDK添加为库。该网址可能类似于/Users/<user>/Downloads/javafx-sdk-11/lib/。完成此操作后,您将注意到在编辑器中现在可以识别JavaFX类。

JavaFX 11项目

  1. 在运行默认项目之前,只需将它们添加到VM选项中:

    --module-path /Users/<user>/Downloads/javafx-sdk-11/lib --add-modules=javafx.controls,javafx.fxml

马文

如果您使用Maven来构建您的项目,请按照下列步骤操作:

  1. 使用JavaFX原型创建Maven项目
  2. 设置JDK 11(指向本地Java 11版本)
  3. 添加JavaFX 11依赖项。

    <dependencies>
        <dependency>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-controls</artifactId>
            <version>11</version>
        </dependency>
        <dependency>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-fxml</artifactId>
            <version>11</version>
        </dependency>
    </dependencies>
    

完成此操作后,您将注意到在编辑器中现在可以识别JavaFX类。

JavaFX 11 Maven项目

您会注意到Maven为您管理了必需的依赖项:它将为javafx.controls添加javafx.base和javafx.graphics,但最重要的是,它将根据您的平台添加必需的分类器。就我而言,是Mac。

这就是您的jarorg.openjfx:javafx-controls:11空的原因,因为存在三个可能的分类器(Windows,Linux和Mac平台),其中包含所有类和本机实现。

如果您仍然想转到.m2存储库并手动从那里获取依赖项,请确保选择正确的依赖项(例如.m2/repository/org/openjfx/javafx-controls/11/javafx-controls-11-mac.jar

  1. 将默认的maven插件替换为此处的插件。

  2. 运行mvn compile javafx:run,它应该可以工作。

类似的作品,以及用于摇篮项目,详细解释在这里

编辑

提到的《入门指南》包含IntelliJ的更新文档和示例项目:


1
路径类似/Users/<user>/Downloads/javafx-sdk-11/lib/,注意lib文件夹。这应该包含所有的JavaFX罐子
何塞·佩雷达

5
如果有人在模块路径上遇到问题,则需要在Windows上看起来像这样:--module-path =“ C:\ Path \ To \ Your \ JavaFX \ lib” --add-modules = javafx.controls,javafx .fxml,javafx.base,javafx.media,javafx.graphics,javafx.swing,javafx.web注意“ =“以及周围的引号。这对我有用,而其他任何方法都没有。此外,请记住,-jar YourJar.jar参数需要在模块路径和add-modules选项之后。
Jalau

4
嗨@JoséPereda。一段时间以来,我一直在努力阅读本指南,但是即使我完全按照您的编写来做,也无法真正使IntelliJ运行我的代码。我仍然收到“错误:java:找不到模块:javafx.fxml”,依此类推。有机会进行私人聊天以帮助我解决此问题吗?谢谢。
Davide3i

1
@jalau谢谢!引号实际上做到了,您应该将此作为答案。
完美的

2
当我为Gradle的示例项目构建发行版并运行它时,出现错误消息:“错误:缺少JavaFX运行时组件,并且运行该应用程序是必需的”
Trejkaz

9

JavaFX不再是JDK 11的问题。以下解决方案可使用IntelliJ进行操作(尚未在NetBeans上进行过尝试):

  1. 将JavaFX全局库添加为依赖项:

    设置->项目结构->模块。在模块中,转到“依赖项”选项卡,然后单击添加“ +”号->库-> Java->从列表中选择JavaFX,然后单击“添加选定项”,然后单击“应用设置”。

  2. 右键单击JavaFX项目中的源文件(src),然后创建一个新的 module-info.java文件。在文件内部编写以下代码:

    module YourProjectName { 
        requires javafx.fxml;
        requires javafx.controls;
        requires javafx.graphics;
        opens sample;
    }
    

    我向您保证,这两个步骤将解决JavaFX的所有问题。

参考:学习编程频道制作了一个You Tube教程,将在5分钟内解释以上所有详细信息。我还建议观看它以解决您的问题:https : //www.youtube.com/watch?v=WtOgoomDewo


8

以上都不对我有用。我花了太多时间来清除出现的其他错误。我发现这是最简单,最好的方法。

这也适用于在Jdk 11、12和OpenJdk12上获取JavaFx!

  • 该视频向您展示了JavaFx Sdk下载
  • 如何将其设置为全局库
  • 设置module-info.java(我更喜欢底部的模块)

module thisIsTheNameOfYourProject {
    requires javafx.fxml;
    requires javafx.controls;
    requires javafx.graphics;
    opens sample;
}

整个过程只花了我5分钟!


将其设置为全球图书馆已于2019.3。您能指出现在的位置吗?
Michael S.

非常感谢!也为我工作!!!赞!
Daniel Boehm

4

快速总结,您可以执行以下任一操作:

  1. 通过José的答案中的--module-path和包括JavaFX模块--add-modules

    要么

  2. 将JavaFX库添加到项目中后(手动或通过maven / gradle导入),请添加module-info.java类似于此答案中指定的文件的文件。(请注意,此解决方案使您的应用程序模块化,因此,如果您使用其他库,则还需要添加语句以在module-info.java文件中包含其模块)。


此答案是Jose答案的补充。

情况是这样的:

  1. 您正在使用最新的Java版本,例如13。
  2. 您有一个JavaFX应用程序作为Maven项目。
  3. 在您的Maven项目中,按照Jose的回答配置了JavaFX插件并设置了JavaFX依赖项。
  4. 您进入扩展了Application的主类的源代码,右键单击它并尝试运行它。
  5. IllegalAccessError尝试启动应用程序时,您遇到一个涉及“未命名模块”的问题。

IllegalAccessError尝试从Intellij Idea运行JavaFX应用程序时生成堆栈跟踪的摘录:

Exception in Application start method
java.lang.reflect.InvocationTargetException
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:567)
    at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(LauncherImpl.java:464)
    at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplication(LauncherImpl.java:363)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:567)
    at java.base/sun.launcher.LauncherHelper$FXHelper.main(LauncherHelper.java:1051)
Caused by: java.lang.RuntimeException: Exception in Application start method
    at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:900)
    at javafx.graphics/com.sun.javafx.application.LauncherImpl.lambda$launchApplication$2(LauncherImpl.java:195)
    at java.base/java.lang.Thread.run(Thread.java:830)
Caused by: java.lang.IllegalAccessError: class com.sun.javafx.fxml.FXMLLoaderHelper (in unnamed module @0x45069d0e) cannot access class com.sun.javafx.util.Utils (in module javafx.graphics) because module javafx.graphics does not export com.sun.javafx.util to unnamed module @0x45069d0e
    at com.sun.javafx.fxml.FXMLLoaderHelper.<clinit>(FXMLLoaderHelper.java:38)
    at javafx.fxml.FXMLLoader.<clinit>(FXMLLoader.java:2056)
    at org.jewelsea.demo.javafx.springboot.Main.start(Main.java:13)
    at javafx.graphics/com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$9(LauncherImpl.java:846)
    at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runAndWait$12(PlatformImpl.java:455)
    at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$10(PlatformImpl.java:428)
    at java.base/java.security.AccessController.doPrivileged(AccessController.java:391)
    at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$11(PlatformImpl.java:427)
    at javafx.graphics/com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:96)
Exception running application org.jewelsea.demo.javafx.springboot.Main

好的,现在您有点卡住,不知道发生了什么。

实际发生的是这样的:

  1. Maven已为您的应用程序成功下载了JavaFX依赖项,因此您无需单独下载依赖项或安装JavaFX SDK或模块分发版或类似的东西。
  2. Idea已成功将模块作为依赖项导入到您的项目中,因此一切都编译正常,所有代码完成,并且一切正常。

所以看来一切都应该没问题。但是,当您运行应用程序时,尝试使用反射实例化应用程序类(调用启动时)和FXML控制器类(加载FXML时)的实例时,JavaFX模块中的代码将失败。没有一些帮助,这种反射的使用在某些情况下可能会失败,从而产生晦涩难懂的印象IllegalAccessError。这是由于Java模块系统安全性功能,除非您明确允许,否则不允许其他模块的代码在类上使用反射(JavaFX应用程序启动器和FXMLLoader都需要在其当前实现中进行反射,才能使它们起作用正确)。

这是该问题的其他一些答案(参考文献module-info.java)出现的地方。

因此,让我们在Java模块中学习速成课程:

关键部分是:

4.9。开门

如果我们需要允许私有类型的反映,但我们不想公开所有代码,则可以使用opens指令公开特定的程序包。

但是请记住,这将打开整个程序包,因此请确保这是您想要的:

module my.module { opens com.my.package; }

因此,也许您不想向全世界打开您的包裹,那么您可以这样做:

4.10。打开…至

好的,因此有时反射非常好,但是我们仍然希望从封装中获得尽可能多的安全性。在本例中,我们可以使用opens…to指令有选择地将包打开到预先批准的模块列表中:

模块my.module {打开com.my.package到moduleOne,moduleTwo等;}

因此,您最终创建了一个src / main / java / module-info.java类,如下所示:

module org.jewelsea.demo.javafx.springboot {
    requires javafx.fxml;
    requires javafx.controls;
    requires javafx.graphics;
    opens org.jewelsea.demo.javafx.springboot to javafx.graphics,javafx.fxml;
}

其中,org.jewelsea.demo.javafx.springboot是包含JavaFX Application类和JavaFX Controller类的软件包的名称(将其替换为您的应用程序的适当软件包名称)。这告诉Java运行时可以使用中的类,javafx.graphicsjavafx.fxmlorg.jewelsea.demo.javafx.springboot包中的类上调用反射。一旦完成,并编译了应用程序,然后重新运行,一切正常,并且IllegalAccessErrorJavaFX使用反射生成的将不再发生。

但是如果您不想创建module-info.java文件怎么办

如果不是使用IDE顶部工具栏中的“运行”按钮直接运行应用程序类,而是:

  1. 转到IDE侧面的Maven窗口。
  2. 选择javafx maven插件target javafx.run
  3. 右键单击它,然后选择Run Maven BuildDebug...

然后,该应用将在没有module-info.java文件的情况下运行。我猜这是因为maven插件足够聪明,可以动态地包含某种设置,即使没有module-info.java文件,该设置也可以使JavaFX类反映该应用程序,尽管我不知道这是如何实现的。

要将设置转移到顶部工具栏中的“运行”按钮,请右键单击javafx.runMaven目标,然后选择目标的选项Create Run/Debug Configuration。然后,您只需从顶部工具栏中选择“运行”即可执行Maven目标。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.