Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

“module not found” error despite “requires” in my module-info.java in JavaFX application

Tags:

java

javafx

I am working on JavaFX project for screen recording. I need to record entire screen. I use monte-screen-recorder dependency.

This is my pom.xml file:

<?xml version="1.0" encoding="UTF-8"?>
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.screenRecorder</groupId>
    <artifactId>ScreenRecorder</artifactId>
    <version>1.0-SNAPSHOT</version>
    <name>ScreenRecorder</name>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <junit.version>5.9.2</junit.version>
    </properties>

    <dependencies>
        <!-- JavaCV dependencies -->
        <dependency>
            <groupId>org.bytedeco</groupId>
            <artifactId>javacv</artifactId>
            <version>1.5.6</version>
        </dependency>
        <dependency>
            <groupId>org.bytedeco</groupId>
            <artifactId>javacv-platform</artifactId>
            <version>1.5.6</version>
        </dependency>
        <dependency>
            <groupId>org.jcodec</groupId>
            <artifactId>jcodec-javase</artifactId>
            <version>0.2.3</version>
        </dependency>
        <!-- JavaFX dependencies -->
        <dependency>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-controls</artifactId>
            <version>17.0.2</version>
        </dependency>
        <dependency>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-media</artifactId>
            <version>17.0.2</version>
        </dependency>
        <dependency>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-fxml</artifactId>
            <version>17.0.2</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/com.github.stephenc.monte/monte-screen-recorder -->
        <dependency>
            <groupId>com.github.stephenc.monte</groupId>
            <artifactId>monte-screen-recorder</artifactId>
            <version>0.7.7.0</version>
        </dependency>
        <dependency>
            <groupId>com.github.kokorin.jaffree</groupId>
            <artifactId>jaffree</artifactId>
            <version>2023.09.10</version>
        </dependency>



    </dependencies>

    <build>
        <plugins>
            <!-- Maven Compiler Plugin -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.11.0</version>
                <configuration>
                    <source>17</source>
                    <target>17</target>
                </configuration>
            </plugin>

            <!-- JavaFX Maven Plugin -->
            <plugin>
                <groupId>org.openjfx</groupId>
                <artifactId>javafx-maven-plugin</artifactId>
                <version>0.0.8</version>
                <executions>
                    <execution>
                        <id>default-cli</id>
                        <configuration>
                            <mainClass>
                                com.screenrecorder.screenrecorder.HelloApplication
                            </mainClass>
                            <launcher>app</launcher>
                            <jlinkZipName>app</jlinkZipName>
                            <jlinkImageName>app</jlinkImageName>
                            <noManPages>true</noManPages>
                            <stripDebug>true</stripDebug>
                            <noHeaderFiles>true</noHeaderFiles>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>

This is my application code:

package com.screenrecorder;

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import org.monte.media.Format;
import org.monte.media.FormatKeys;
import org.monte.media.math.Rational;
import org.monte.screenrecorder.ScreenRecorder;

import java.awt.*;

import static org.monte.media.FormatKeys.MediaTypeKey;
import static org.monte.media.VideoFormatKeys.ENCODING_AVI_TECHSMITH_SCREEN_CAPTURE;

public class ScreenRecorderApp extends Application {

    private ScreenRecorder screenRecorder;
    private boolean isRecording = false;

    @Override
    public void start(Stage primaryStage) throws Exception {
        Button startButton = new Button("Start Recording");
        startButton.setOnAction(event -> startRecording());

        Button stopButton = new Button("Stop Recording");
        stopButton.setOnAction(event -> stopRecording());

        VBox root = new VBox(10, startButton, stopButton);
        Scene scene = new Scene(root, 300, 200);

        primaryStage.setScene(scene);
        primaryStage.setTitle("Screen Recorder");
        primaryStage.show();
    }

    private void startRecording() {
        try {
            GraphicsConfiguration gc = GraphicsEnvironment.getLocalGraphicsEnvironment()
                    .getDefaultScreenDevice()
                    .getDefaultConfiguration();

            screenRecorder = new ScreenRecorder(gc, null, new Format(MediaTypeKey, FormatKeys.EncodingKey, ENCODING_AVI_TECHSMITH_SCREEN_CAPTURE,
                    FormatKeys.FrameRateKey, Rational.valueOf(15)), new Format(MediaTypeKey, FormatKeys.EncodingKey, "black", FormatKeys.FrameRateKey, Rational.valueOf(30)),
                    null);
            screenRecorder.start();

            isRecording = true;
            System.out.println("Recording started...");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void stopRecording() {
        if (isRecording && screenRecorder != null) {
            try {
                screenRecorder.stop();
                System.out.println("Recording stopped...");
            } catch (Exception e) {
                e.printStackTrace();
            }
            isRecording = false;
        }
    }

    public static void main(String[] args) {
        launch(args);
    }
}

This is my module-info.java file:

module com.screenrecorder {
    requires javafx.controls;
    requires javafx.fxml;
    requires javafx.media;
    requires java.desktop;
    requires jcodec.javase;
    requires monte.screen.recorder;

    opens com.screenrecorder to javafx.fxml;
    exports com.screenrecorder;

}

When I run my application, I get this error:

java: module not found: monte.screen.recorder

i don't know why i am facing this error. what i need to change in my code?

i am trying some changes but still facing same error.

try to use different library but i don't find any one.

like image 425
Anup Panchal Avatar asked Oct 22 '25 20:10

Anup Panchal


1 Answers

Why you cannot use the screen recorder jar as a module

The reason you can't use the screen recorder jar as a module is because the jar contains classes that are not in any named Java package.

Even if you require a valid module name, there are other reasons why the jar might fail to function as a module (e.g. package conflicts), because the jar was never created to be used as a module. It might still work (or it might not).

To test some of these aspects, you can use the jar tool to get module information from the jar:

jar --describe-module --file ~/.m2/repository/com/github/stephenc/monte/monte-screen-recorder/0.7.7.0/monte-screen-recorder-0.7.7.0.jar

And you will receive output similar to the following:

Unable to derive module descriptor for: ~/.m2/repository/com/github/stephenc/monte/monte-screen-recorder/0.7.7.0/monte-screen-recorder-0.7.7.0.jar
ScreenRecorder.class found in top-level directory (unnamed package not allowed in module)

Determining the correct module name for your screen recorder dependency

Understand how automatic modules work. As others have noted in the comments, use the correct name for the module.

As the jar has no module-info.java or Automatic-Module-Name, the name used would be monte.screen.recorder, as based on the jar name to module name mapping rule from the ModuleFinder documentation linked by VGR in comments.

This is because the artifactId in the dependency is monte-screen-recorder, which indicates the jar name would be monte-screen-recorder.jar.

You can require the jar as a module in your module-info.java using:

requires monte.screen.recorder;

But this is what you already have, so it is not the usage of an incorrect module name that is causing your issue.

Recommendation: Make your project non-modular

You also have other dependencies that you aren't using as modules (e.g., javacv and jaffree).

When you have a lot of non-modular dependencies like this, I don't recommend making your application modular. You experience a lot of the pain of using the module system, with few of its benefits realized.

Instead, run JavaFX and the core JDK off the module path (as that is how they are programmed to work), but make your application non-modular (delete the module-info.java). The Getting Started instructions at openjfx.io include information on various ways to develop non-modular applications using JavaFX technology.

Not using modules means that you can't link your application using jlink. But, jlink does not work for automatic modules anyway, so your jlink configuration in your pom.xml cannot work regardless of whether your application is modular.

like image 175
jewelsea Avatar answered Oct 25 '25 10:10

jewelsea