Module Error When Running Javafx Media Application

Module error when running JavaFx media application

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. 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.

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.



The Problem

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:

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

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.

Your Error

This is your error:

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

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?

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.

But... You Used the Module-Path

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

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.



The Solution

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

  1. Include the module in your --add-modules argument.

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

    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.

    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).

  2. 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;
    }

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

    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.

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.


If you use Maven, you can see how to rely on the JavaFX media module here as a dependency here:

  • JavaFX media player import (Maven)

Java FX Modular Application, Module not found (Java 17, Intellij)

Steps to address your issue

  1. Ensure that you are using the most recent stable version of Idea (currently 2021.3.2), Java and JavaFX (currently 17.0.2).
  2. Discard your current project.
  3. Create a new project.
    • Follow the instructions at Create a new JavaFX project provided by Idea on how to use their wizard.
    • If you follow the instructions exactly it should work.
  4. You don't need to add "the Java FX lib" to the project manually.
    • The wizard will create a dependency in Maven or Gradle which includes the most common JavaFX modules.
    • You don't need to download or use the JavaFX SDK mentioned at openjfx.io.
  5. You don't need to explicitly set any VM arguments such as --add-modules the wizard will create the a module-info.java file which references the modules.

Before proceeding any further, make sure that the basic generated project build and runs in your environment (according to the build and execution instructions documented by IntelliJ for the new JavaFX project wizard).

Using additional JavaFX modules

If you want to use additional JavaFX modules (e.g. javafx.media or javafx.web):

  1. Add the additional modules manually to the maven or gradle build file.
  2. Reimport the build file into the Idea project.
  3. Add requires clauses form the modules to the module-info.java.

Making your application non-modular

Even if your application is made non-modular, you still need to have JavaFX modules on the module path as that is the only way the execution of JavaFX is supported.

If you don't want a modular application, you can delete the module-info.java file and manually add VM arguments for the module path to the JavaFX and an --add-modules switch.

I do not advise doing this step unless:

  • You have a good reason not to have a non-modular application (e.g. rely on 3rd party dependencies which do not integrate easily with the Java module system), AND
  • You have knowledge about how to make non-modular JavaFX applications.

Cause of the module find exception

The reason for your specific error:

java.lang.module.FindException: Module com.example.hudrava_test not found

is because you don't have module-info.java for a module with that name on the module path. Note that is not a JavaFX module name, but something you have specified. You have tried to run the application by specifying a class name within the non-existent module, e.g.

java --module-path <somepath> -m com.example.hudrava_test/com.example.hudrava_test.HelloApplication

You can find out further info about that in:

  • java.lang.module.FindException: Module not found.

However, you should not need to manually take the steps outlined in that answer, because, when you create a new project using the new JavaFX wizard, it will automatically create a module-info.java file and place your application's build output on the modulepath.

So the error was caused by something you did after creating the project with the wizard (I don't know what). When you create a new project, you should not have the error.

On module naming and underscores

The Jenkov module tutorial states:

A Java module name follows the same naming rules as Java packages. However, you should not use underscores (_) in module names (or package names, class names, method names, variable names etc.) from Java 9 and forward, because Java wants to use underscore as a reserved identifier in the future.

It is recommended to name a Java module the same as the name of the root Java package contained in the module - if that is possible (some modules might contain multiple root packages).

So, it is inadvisable to have underscores in either your module or your package name.

More info on module naming suggestions is provided in:

  • How should I name my Java 9 module?

Problem starting my application using JavaFX

I had similar issue. For me solution was to
add following configuration :

--add-modules javafx.controls,javafx.fxml

insted of just

--add-modules javafx.controls

Javafx MediaPlayer runs into error whenever you disconnect bluetooth headphones

The problem with your recovery is that you are seeking too soon. The docs for seek state that it does nothing while the media player is stopped, but you aren't waiting for the state to change after calling play().

Try this:

    mediaPlayer.setOnError( () -> {
mediaPlayer = new MediaPlayer(media);
System.out.println(durationBackup.toMillis());
mediaPlayer.setOnPlaying(() ->{
mediaPlayer.seek(durationBackup);
mediaPlayer.setOnPlaying(null);
});
mediaPlayer.play();
});

JavaFX MediaPlayer import

If you define a module-info.java file and you want to use the javafx.media module, you need to require that module in your module-info (as suggested by kleopatra in comments).

module com.example.demo {
requires javafx.controls;
requires javafx.fxml;
requires javafx.media;

opens com.example.demo to javafx.fxml;
exports com.example.demo;
}

The JavaFX modules are named in the javadoc.

Oracle provide a brief introduction to the module system, which you should understand when you use it.

As you are using Maven and JavaFX 17.0.0.1, you also need a dependency in Maven on that version of the javafx-media module.

<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-media</artifactId>
<version>17.0.0.1</version>
</dependency>

For a full discussion of this topic, see:

  • Module error when running JavaFx media application

JavaFX trouble importing

As javaFX is already bundled with JDK 8. I would suggest, try using java 8 instead, if it works, then your previous setup wasn't correct.



Related Topics



Leave a reply



Submit