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

查看:1964
本文介绍了运行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参数,请查看

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

  • 模块名称
  • 该模块的依赖关系(即该模块所依赖的其他模块)
  • 它显式提供给其他模块的软件包(该模块中的所有其他软件包隐式地对其他模块不可用)
  • 它提供的服务
  • 消费的服务
  • 它还可以反射其他哪些模块
  • the module’s name
  • the module’s dependencies (that is, other modules this module depends on)
  • the packages it explicitly makes available to other modules (all other packages in the module are implicitly unavailable to other modules)
  • the services it offers
  • the services it consumes
  • to what other modules it allows reflection

随着模块的引入,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?

未命名模块是class-path上所有类所属的模块.这意味着javafx.media模块被放在类路径上并且丢失了其标识.这样做的结果是,javafx.graphics模块声明的所有合格的export/opens指令(向javafx.media模块授予必要的访问权限)不再适用-因此IllegalAccessError.

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.

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入门指南显示了如何在每个版本中为JavaFX配置VM选项主要的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).

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

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以反射方式实例化您的应用程序类.对于FXML控制器,也有类似的要求(合格的opens) 和其他需要私有反射访问的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.

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

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