Search code examples
javamavenintellij-ideajavafxjar

Error when trying to make a fat jar with maven in JavaFX on Intellij


I have been trying to create a jar with maven and the maven-shade-plugin for my JavaFX project following this tutorial. https://www.youtube.com/watch?v=EyYb0GmtEX4.

I can create the jar file but when I run it, it gives me the error: Error: Could not find or load main class com.example.pleasework.com.example.pleasework.Main_1

Caused by: java.lang.ClassNotFoundException: com.example.pleasework.com.example.pleasework.Main_1

I have already tried adding java --module-path /path/to/java-fx-libs/ --add-modules javafx.controls,javafx.fxml MyMainClass to vm options but it just changes the error to Error: Could not find or load main class Java. Also, I have a second Main file that runs my first Main file which extends Application.

I am using IntelliJ and created my project through IntelliJ's built-in JavaFX project with Maven. I can run my project normally and it works fine, but when I try to run the shaded jar I generated through Maven's shade plugin I get these errors.

Here is my project structure: enter image description here

Here is my 2nd Main file

package com.example.pleasework;

public class Main_1 {
    public static void main(String[] args) {
        HelloApplication.main(args);
    }
}

Here is my first main file

package com.example.pleasework;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.stage.Stage;

import java.io.IOException;

public class HelloApplication extends Application {
    @Override
    public void start(Stage stage) throws IOException {
        FXMLLoader fxmlLoader = new FXMLLoader(HelloApplication.class.getResource("hello-view.fxml"));
        Scene scene = new Scene(fxmlLoader.load(), 320, 240);
        stage.setTitle("Hello!");
        stage.setScene(scene);
        stage.show();
    }

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

Here is my pom.xml

<?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.example</groupId>
    <artifactId>PleaseWork</artifactId>
    <version>1.0-SNAPSHOT</version>
    <name>PleaseWork</name>

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

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

        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-api</artifactId>
            <version>${junit.version}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-engine</artifactId>
            <version>${junit.version}</version>
            <scope>test</scope>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.seleniumhq.selenium/selenium-java -->
        <dependency>
            <groupId>org.seleniumhq.selenium</groupId>
            <artifactId>selenium-java</artifactId>
            <version>4.1.1</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/io.github.bonigarcia/webdrivermanager -->
        <dependency>
            <groupId>io.github.bonigarcia</groupId>
            <artifactId>webdrivermanager</artifactId>
            <version>5.0.3</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/com.opencsv/opencsv -->
        <dependency>
            <groupId>com.opencsv</groupId>
            <artifactId>opencsv</artifactId>
            <version>5.5.2</version>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <source>11</source>
                    <target>11</target>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.openjfx</groupId>
                <artifactId>javafx-maven-plugin</artifactId>
                <version>0.0.8</version>
                <executions>
                    <execution>
                        <!-- Default configuration for running with: mvn clean javafx:run -->
                        <id>default-cli</id>
                        <configuration>
                            <mainClass>com.example.pleasework/com.example.pleasework.Main_1</mainClass>
                            <launcher>app</launcher>
                            <jlinkZipName>app</jlinkZipName>
                            <jlinkImageName>app</jlinkImageName>
                            <noManPages>true</noManPages>
                            <stripDebug>true</stripDebug>
                            <noHeaderFiles>true</noHeaderFiles>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-shade-plugin</artifactId>
                <executions>
                    <execution>
                        <id>default-compile</id>
                        <configuration>
                            <compilerArgument>-proc:none</compilerArgument>
                            <includes>
                                <include>fun/n/learn/annotation/LogMeCustomAnnotationProcessor.java</include>
                                <!--include dependencies required for LogMeCustomAnnotationProcessor -->
                            </includes>
                        </configuration>
                    </execution>
                    <execution>
                        <goals>
                            <goal>shade</goal>
                        </goals>
                        <configuration>
                            <shadedArtifactAttached>true</shadedArtifactAttached>
                            <transformers>
                                <transformer implementation=
                                                     "org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                                    <mainClass>com.example.pleasework/com.example.pleasework.Main_1</mainClass>
                                </transformer>
                            </transformers>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>

Solution

  • The error message indicates that you have to specify the main class without module name. Just use the fully qualified class name there. A fully qualified never contains a slash as it is not a path name. So in your case the fully qualified class name is including the XML tags around (the main class is used two times in your pom.xml and have to be corrected in both cases):

    <mainClass>com.example.pleasework.Main_1</mainClass>
    

    You can build the fully qualified class name yourself: use the string from the package declaration of the class you want to reference, add a dot and then write the class name from the class declaration and voila you have the fully qualified class name.