运行 JavaFx 媒体应用程序时出现模块错误 [英] Module error when running JavaFx media application

查看:27
本文介绍了运行 JavaFx 媒体应用程序时出现模块错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我使用以下命令运行我的 JavaFX 11 应用程序时:

When I run my JavaFX 11 application with the following command:

/usr/lib/jvm/java-11-openjdk-amd64/bin/java 
-p ~/.m2/repository/org/openjfx/javafx-swing/11/javafx-swing-11.jar:
~/.m2/repository/org/openjfx/javafx-swing/11/javafx-swing-11-linux.jar:
~/.m2/repository/org/openjfx/javafx-graphics/11/javafx-graphics-11.jar:
~/.m2/repository/org/openjfx/javafx-graphics/11/javafx-graphics-11-linux.jar:
~/.m2/repository/org/openjfx/javafx-base/11/javafx-base-11.jar:
~/.m2/repository/org/openjfx/javafx-base/11/javafx-base-11-linux.jar:
~/.m2/repository/org/openjfx/javafx-controls/11/javafx-controls-11.jar:
~/.m2/repository/org/openjfx/javafx-controls/11/javafx-controls-11-linux.jar:
~/.m2/repository/org/openjfx/javafx-media/11/javafx-media-11.jar:
~/.m2/repository/org/openjfx/javafx-media/11/javafx-media-11-linux.jar 
--add-modules javafx.controls,javafx.graphics
-classpath ~/development/intellij/OpenPatrician/OpenPatricianStandalone/target/classes:
~/.OpenPatrician/plugins/maps/MinimalMap-Plugin.jar:
~/development/intellij/OpenPatrician/OpenPatricianDisplay/target/classes:
~/.m2/repository/ch/sahits/sahitsUtil/1.2.4/sahitsUtil-1.2.4.jar:
~/.m2/repository/junit/junit/4.12/junit-4.12.jar:
~/.m2/repository/org/hamcrest/hamcrest-core/1.3/hamcrest-core-1.3.jar:
~/.m2/repository/org/springframework/boot/spring-boot-starter-log4j2/2.1.0.RELEASE/spring-boot-starter-log4j2-2.1.0.RELEASE.jar:
~/.m2/repository/org/apache/logging/log4j/log4j-slf4j-impl/2.11.1/log4j-slf4j-impl-2.11.1.jar:
~/.m2/repository/org/slf4j/slf4j-api/1.7.25/slf4j-api-1.7.25.jar:
~/.m2/repository/org/apache/logging/log4j/log4j-api/2.11.1/log4j-api-2.11.1.jar:
~/.m2/repository/org/apache/logging/log4j/log4j-core/2.11.1/log4j-core-2.11.1.jar:
~/.m2/repository/org/apache/logging/log4j/log4j-jul/2.11.1/log4j-jul-2.11.1.jar:
~/.m2/repository/org/slf4j/jul-to-slf4j/1.7.25/jul-to-slf4j-1.7.25.jar:
~/.m2/repository/commons-cli/commons-cli/1.4/commons-cli-1.4.jar:
~/development/intellij/OpenPatrician/OpenPatricianImage/target/classes:
~/development/intellij/OpenPatrician/OpenPatricianModel/target/classes:
~/development/intellij/OpenPatrician/GameEvent/target/classes:
~/.m2/repository/org/glassfish/jaxb/jaxb-runtime/2.3.1/jaxb-runtime-2.3.1.jar:
~/.m2/repository/org/glassfish/jaxb/txw2/2.3.1/txw2-2.3.1.jar:
~/.m2/repository/com/sun/istack/istack-commons-runtime/3.0.7/istack-commons-runtime-3.0.7.jar:
~/.m2/repository/org/jvnet/staxex/stax-ex/1.8/stax-ex-1.8.jar:
~/.m2/repository/com/sun/xml/fastinfoset/FastInfoset/1.2.15/FastInfoset-1.2.15.jar:
~/.m2/repository/javax/activation/javax.activation-api/1.2.0/javax.activation-api-1.2.0.jar:
~/.m2/repository/org/openjfx/javafx-swing/11/javafx-swing-11.jar:
~/.m2/repository/org/openjfx/javafx-swing/11/javafx-swing-11-linux.jar:
~/.m2/repository/org/openjfx/javafx-graphics/11/javafx-graphics-11.jar:
~/.m2/repository/org/openjfx/javafx-graphics/11/javafx-graphics-11-linux.jar:
~/.m2/repository/org/openjfx/javafx-base/11/javafx-base-11.jar:
~/.m2/repository/org/openjfx/javafx-base/11/javafx-base-11-linux.jar:
~/development/intellij/OpenPatrician/OpenPatricianSound/target/classes:
~/development/intellij/OpenPatrician/OpenPatricianUtilities/target/classes:
~/.m2/repository/org/springframework/spring-beans/5.1.2.RELEASE/spring-beans-5.1.2.RELEASE.jar:
~/.m2/repository/org/openjfx/javafx-controls/11/javafx-controls-11.jar:
~/.m2/repository/org/openjfx/javafx-controls/11/javafx-controls-11-linux.jar:
~/.m2/repository/commons-io/commons-io/2.6/commons-io-2.6.jar:
~/.m2/repository/com/thoughtworks/xstream/xstream/1.4.10/xstream-1.4.10.jar:
~/.m2/repository/xmlpull/xmlpull/1.1.3.1/xmlpull-1.1.3.1.jar:
~/.m2/repository/xpp3/xpp3_min/1.1.4c/xpp3_min-1.1.4c.jar:
~/.m2/repository/javax/xml/bind/jaxb-api/2.3.1/jaxb-api-2.3.1.jar:
~/.m2/repository/javax/annotation/javax.annotation-api/1.3.2/javax.annotation-api-1.3.2.jar:
~/.m2/repository/org/openjfx/javafx-media/11/javafx-media-11.jar:
~/.m2/repository/org/openjfx/javafx-media/11/javafx-media-11-linux.jar:
~/.m2/repository/org/springframework/spring-context/5.1.2.RELEASE/spring-context-5.1.2.RELEASE.jar:
~/.m2/repository/org/springframework/spring-aop/5.1.2.RELEASE/spring-aop-5.1.2.RELEASE.jar:
~/.m2/repository/org/springframework/spring-expression/5.1.2.RELEASE/spring-expression-5.1.2.RELEASE.jar:
~/.m2/repository/org/springframework/spring-oxm/5.1.2.RELEASE/spring-oxm-5.1.2.RELEASE.jar:
~/.m2/repository/com/google/guava/guava/24.1-jre/guava-24.1-jre.jar:
~/.m2/repository/com/google/code/findbugs/jsr305/1.3.9/jsr305-1.3.9.jar:
~/.m2/repository/org/checkerframework/checker-compat-qual/2.0.0/checker-compat-qual-2.0.0.jar:
~/.m2/repository/com/google/errorprone/error_prone_annotations/2.1.3/error_prone_annotations-2.1.3.jar:
~/.m2/repository/com/google/j2objc/j2objc-annotations/1.1/j2objc-annotations-1.1.jar:
~/.m2/repository/org/codehaus/mojo/animal-sniffer-annotations/1.14/animal-sniffer-annotations-1.14.jar:
~/development/intellij/OpenPatrician/OpenPatricianJavaFX/target/classes:
~/development/intellij/OpenPatrician/OpenPatricianGameEvent/target/classes:
~/development/intellij/OpenPatrician/OpenPatricianClientServerInterface/target/classes:
~/.m2/repository/org/springframework/boot/spring-boot-starter-aop/2.1.0.RELEASE/spring-boot-starter-aop-2.1.0.RELEASE.jar:
~/.m2/repository/org/springframework/boot/spring-boot-starter/2.1.0.RELEASE/spring-boot-starter-2.1.0.RELEASE.jar:
~/.m2/repository/org/yaml/snakeyaml/1.23/snakeyaml-1.23.jar:
~/.m2/repository/org/aspectj/aspectjweaver/1.9.2/aspectjweaver-1.9.2.jar:
~/development/intellij/OpenPatrician/OpenPatricianServer/target/classes:
~/development/intellij/OpenPatrician/OpenPatricianEngine/target/classes:
~/.m2/repository/com/carrotsearch/hppc/0.7.2/hppc-0.7.2.jar:
~/.m2/repository/org/springframework/spring-core/5.1.2.RELEASE/spring-core-5.1.2.RELEASE.jar:
~/.m2/repository/org/springframework/spring-jcl/5.1.2.RELEASE/spring-jcl-5.1.2.RELEASE.jar:
~/.m2/repository/org/reflections/reflections/0.9.11/reflections-0.9.11.jar:
~/.m2/repository/org/javassist/javassist/3.21.0-GA/javassist-3.21.0-GA.jar:
~/development/intellij/OpenPatrician/OpenPatricianData/target/classes:
~/.m2/repository/org/projectlombok/lombok/1.18.2/lombok-1.18.2.jar:
~/.m2/repository/org/springframework/boot/spring-boot-devtools/2.1.0.RELEASE/spring-boot-devtools-2.1.0.RELEASE.jar:
~/.m2/repository/org/springframework/boot/spring-boot/2.1.0.RELEASE/spring-boot-2.1.0.RELEASE.jar:
~/.m2/repository/org/springframework/boot/spring-boot-autoconfigure/2.1.0.RELEASE/spring-boot-autoconfigure-2.1.0.RELEASE.jar 
ch.sahits.game.openpatrician.standalone.OpenPatricianApplication

我遇到了这个错误:

Exception in thread "JavaFX Application Thread" java.lang.IllegalAccessError: class com.sun.media.jfxmediaimpl.NativeMediaManager (in unnamed module @0x4d7be377) cannot access class com.sun.glass.utils.NativeLibLoader (in module javafx.graphics) because module javafx.graphics does not export com.sun.glass.utils to unnamed module @0x4d7be377
    at com.sun.media.jfxmediaimpl.NativeMediaManager.lambda$new$0(NativeMediaManager.java:136)
    at java.base/java.security.AccessController.doPrivileged(Native Method)
    at com.sun.media.jfxmediaimpl.NativeMediaManager.<init>(NativeMediaManager.java:107)
    at com.sun.media.jfxmediaimpl.NativeMediaManager$NativeMediaManagerInitializer.<clinit>(NativeMediaManager.java:78)
    at com.sun.media.jfxmediaimpl.NativeMediaManager.getDefaultInstance(NativeMediaManager.java:90)
    at com.sun.media.jfxmedia.MediaManager.canPlayProtocol(MediaManager.java:78)
    at com.sun.media.jfxmedia.locator.Locator.<init>(Locator.java:239)
    at com.sun.media.jfxmediaimpl.NativeMediaAudioClip.<init>(NativeMediaAudioClip.java:53)
    at com.sun.media.jfxmediaimpl.NativeMediaAudioClip.load(NativeMediaAudioClip.java:63)
    at com.sun.media.jfxmediaimpl.AudioClipProvider.load(AudioClipProvider.java:66)
    at com.sun.media.jfxmedia.AudioClip.load(AudioClip.java:135)
    at javafx.scene.media.AudioClip.<init>(AudioClip.java:83)
    at ch.sahits.game.openpatrician.sound.impl.LoopTrack.lambda$new$0(LoopTrack.java:26)
    at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$10(PlatformImpl.java:428)
    at java.base/java.security.AccessController.doPrivileged(Native Method)
    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)
    at javafx.graphics/com.sun.glass.ui.gtk.GtkApplication._runLoop(Native Method)
    at javafx.graphics/com.sun.glass.ui.gtk.GtkApplication.lambda$runLoop$11(GtkApplication.java:277)
    at java.base/java.lang.Thread.run(Thread.java:834)

据我所知,这个异常是我的模块设置有问题,但我不清楚我需要更改什么:

As I understand this exception there is something wrong with my module setup, but I am not clear what I need to change:

  • --add-modules 添加其他模块,以及哪些?
  • --add-opens 添加到使用哪些模块的命令
  • 完全不同的东西?
  • Add additional modules to --add-modules and which?
  • Add --add-opens to the command with which modules
  • Something completely different?

推荐答案

TL;DR: 您需要确保将 javafx.media 解析为来自模块路径.您可以通过以下任一方式执行此操作:

TL;DR: You need to make sure javafx.media is resolved as a module from the module-path. You can do this by either:

  1. 将其包含在 VM 参数中:--add-modules javafx.controls,javafx.media
  2. 或者使您自己的代码模块化,向您的模块描述符添加适当的 requires javafx.media; 指令,并使用 --module 启动您的应用程序.莉>
  1. Including it in the VM arguments: --add-modules javafx.controls,javafx.media
  2. Or making your own code modular, adding an appropriate requires javafx.media; directive to your module descriptor, and using --module to launch your application.

如果您不确定如何或在何处设置 IDE 和/或构建工具中的 VM 参数,请查看 JavaFX 入门.

If you're not sure how or where to set the VM arguments in your IDE and/or build tool, check out Getting Started with JavaFX.

该错误与 Java 9 中添加的 Java 平台模块系统有关.如果您不知道模块是什么以及它们如何工作,请查看此博客:了解 Java 9 模块.这是一小段摘录:

The error is related to the Java Platform Module System, added in Java 9. If you're not aware of what modules are and how they work, check out this blog: Understanding Java 9 Modules. Here's a small excerpt:

模块化在包之上添加了更高级别的聚合.关键的新语言元素是模块——一组唯一命名的、可重用的相关包,以及资源(如图像和 XML 文件)和一个模块描述符,用于指定

Modularity adds a higher level of aggregation above packages. The key new language element is the module—a uniquely named, reusable group of related packages, as well as resources (such as images and XML files) and a module descriptor specifying

  • 模块名称
  • 模块的依赖项(即该模块依赖的其他模块)
  • 它明确提供给其他模块的包(模块中的所有其他包对其他模块隐式不可用)
  • 它提供的服务
  • 它使用的服务
  • 它允许反射到哪些其他模块

随着模块的引入,JavaFX 也被模块化了.它现在由七个模块组成,从 它的 Javadoc 可以看出.这些模块在它们之间共享它们的一些内部结构,但不与应用程序开发人员共享.这是通过合格导出/打开指令完成的.

With the introduction of modules, JavaFX was also modularized. It is now made up of seven modules, as can be seen by its Javadoc. These modules share some of their internals between themselves, but not with application developers. This is accomplished through qualified exports/opens directives.

这是你的错误:

java.lang.IllegalAccessError: class com.sun.media.jfxmediaimpl.NativeMediaManager (in unnamed module @0x4d7be377) cannot access class com.sun.glass.utils.NativeLibLoader (in module javafx.graphics) because module javafx.graphics does not export com.sun.glass.utils to unnamed module @0x4d7be377

它告诉您未命名模块中的一个类正在尝试访问另一个命名模块中的类:javafx.graphics.但是,后一个模块不会将所需的包导出到至少未命名的模块.查看错误消息和给定的类名,我们可以推断未命名模块中的类是 JavaFX 媒体实现的一部分.这表明类应该javafx.media模块中.那为什么错误会提到未命名的模块呢?

It's telling you a class in the unnamed module is attempting to access a class in a different, named module: javafx.graphics. However, the latter module does not export the needed package to at least the unnamed module. Looking at the error message and the given class names, we can deduce that the class in the unnamed module is part of JavaFX's media implementation. This suggests the class should be in the javafx.media module. Then why does the error mention the unnamed module?

未命名模块是类路径上所有类所属的模块.这意味着 javafx.media 模块被放在类路径上并失去了它的身份.这样做的结果是,由 javafx.graphics 模块声明的所有合格的导出/打开指令不再适用于 javafx.media 模块,因此不再适用非法访问错误.

The unnamed module is the module all classes on the class-path belong to. What this means is that the javafx.media module was put on the class-path and lost its identity. A consequence of this is that all the qualified exports/opens directives declared by the javafx.graphics module which grant the javafx.media module the necessary access no longer apply—hence the IllegalAccessError.

从您在问题中提供的命令行,我们可以看到 javafx-media-11.jar 文件位于模块路径 (-p) 上.那么问题出在哪里呢?该问题是由于将媒体 JAR 文件 放在模块路径 类路径上,同时未能确保 javafx.media 模块被解析为一个模块.

From the command line you provided in your question we can see the javafx-media-11.jar file was placed on the module-path (-p). So what is the problem? The problem is caused by placing the media JAR file on both the module-path and the class-path, while simultaneously failing to ensure the javafx.media module is resolved as a module.

模块解析的算法由 java.lang.module 包文档.基本上,它从一组根模块开始,然后递归地枚举 requires 指令.根模块由 --add-modules--module 参数确定.您的代码不是模块化的,这意味着您不使用 --module,并且您有:

The algorithm for module resolution is described by the java.lang.module package documentation. Basically, it starts with a set of root modules and then recursively enumerates the requires directives. The root modules are determined by the --add-modules and --module arguments. Your code isn't modular, meaning you don't use --module, and you have:

--add-modules javafx.controls,javafx.graphics

换句话说,没有任何根模块直接或间接需要 javafx.media 模块,因此它永远不会被解析.由于这些类也在类路径上,它们仍然可以找到,但现在位于未命名的模块中.如果您还没有在类路径上放置 JavaFX 依赖项,那么您将收到 ClassNotFoundException.

In other words, none of the root modules directly or indirectly require the javafx.media module, thus it is never resolved. Since the classes are also on the class-path they're still found, but now in the unnamed module. If you had not placed the JavaFX dependencies on the class-path as well then you'd be getting a ClassNotFoundException.

解决方案很简单:确保javafx.media 模块已解析.至少有两种方法可以做到这一点:

The solution is simple: Make sure the javafx.media module is resolved. There are at least two ways to accomplish this:

  1. 将模块包含在您的 --add-modules 参数中.

--add-modules javafx.controls,javafx.media

注意您不需要指定 javafx.graphics 模块,因为它会被其他模块隐式拉入;javafx.controlsjavafx.media 都需要 javafx.graphics.在这种情况下,相同的一般推理也适用于 javafx.base 模块.

Note you don't need to specify the javafx.graphics module as it'll be pulled in implicitly by the other modules; both javafx.controls and javafx.media require javafx.graphics. The same general reasoning also applies to the javafx.base module in this case.

JavaFX 入门 指南展示了如何在每个主要 IDE(即 IntelliJ、Eclipse 和 NetBeans)和构建工具(即 Maven 和 Gradle).

The Getting Started with JavaFX guides show how to configure the VM options for JavaFX in each of the major IDEs (i.e. IntelliJ, Eclipse, and NetBeans) and build tools (i.e. Maven and Gradle).

使您自己的代码模块化并添加必要的 requires 指令.

Make your own code modular and add the necessary requires directives.

module app {
    requires javafx.controls;
    requires javafx.media;

    // replace with your Application class' package
    exports com.example.app to javafx.graphics;
}

然后确保使用 --module 启动您的应用程序.

Then make sure to launch your application with --module.

注意对 javafx.graphics 的合格导出.这是必需的,以便 JavaFX 反射性地实例化您的应用类.有类似的要求(合格的opens)用于 FXML 控制器和其他需要私有反射访问的 API.

Notice the qualified exports to javafx.graphics. This is required in order for JavaFX to reflectively instantiate your application class. There are similar requirements (qualified opens) for FXML controllers and other APIs which require private reflective access.

还有另一种选择:将所有内容放在类路径上,包括 JavaFX 模块,并完全忽略 JPMS 模块.如果你这样做,你的主类不能Application的子类.您必须创建一个单独的启动器类来简单地启动 JavaFX.警告:此方法不支持.

There is another option: Place everything on the class-path, including the JavaFX modules, and ignore JPMS modules completely. If you do this your main-class must not be a subclass of Application. You'd have to create a separate launcher class that simply launches JavaFX. Warning: This approach is not supported.

这篇关于运行 JavaFx 媒体应用程序时出现模块错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆