Search code examples
javaspring-bootmavenexelaunch4j

Launch4j Maven plugin version 2.0.1 Could not find or load main class


First of all I have read a lot of posts about this problem on internet as well as on stackoverflow when nothing worked out I decided to ask myself.

I am trying to create a simple exe of my spring boot application using Launch4j maven plugin. The generated exe is unable to find the main class. I get the below error on my command line:

Error: Could not find or load main class com.XXX.scheduler.SchedulerApplication
Caused by: java.lang.ClassNotFoundException: com.XXX.scheduler.SchedulerApplication

Below is my pom.xml in which I have tried multiple combinations to get this thing working. NOTE: The jar alone just works fine.

<?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>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.4.5</version>
        <relativePath/>
        <!-- lookup parent from repository -->
    </parent>
    <groupId>com.XXX</groupId>
    <artifactId>scheduler</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>scheduler</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>11</java.version>
    </properties>
    <!-- <properties>
        <maven.compiler.target>1.8</maven.compiler.target>
        <maven.compiler.source>1.8</maven.compiler.source>
    </properties> -->
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-quartz</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
            <plugin>
                <groupId>com.akathist.maven.plugins.launch4j</groupId>
                <artifactId>launch4j-maven-plugin</artifactId>
                <version>2.0.1</version>
                <executions>
                    <execution>
                        <id>l4j-clui</id>
                        <phase>package</phase>
                        <goals>
                            <goal>launch4j</goal>
                        </goals>
                        <configuration>
                            <dontWrapJar>true</dontWrapJar>
                            <headerType>console</headerType>
                            <!-- <headerType>gui</headerType> -->
                            <!-- <jar>${project.build.directory}/scheduler-0.0.1-SNAPSHOT.jar</jar> -->
                            <jar>${artifactId}-${version}.jar</jar>
                            <!-- <jar>${project.build.directory}/${artifactId}-${version}.jar</jar> -->
                            <outfile>${project.build.directory}/test.exe</outfile>
                            <downloadUrl>http://java.com/download</downloadUrl>
                            <classPath>
                                <mainClass>com.XXX.scheduler.SchedulerApplication</mainClass>
                                <!-- <mainClass>SchedulerApplication</mainClass> -->
                                <!-- <mainClass>com/XXX/scheduler/SchedulerApplication</mainClass> -->
                                <addDependencies>false</addDependencies>
                                <preCp>anything</preCp>
                            </classPath>
                            <!-- <icon>src/main/resources/icon/application.ico</icon> -->
                            <jre>
                                <!-- <path>../jdk15</path> -->
                                <!-- <jdkPreference>preferJdk</jdkPreference> -->
                                <jdkPreference>preferJre</jdkPreference>
                                <minVersion>11</minVersion>
                                <!-- <minVersion>1.8.0_212</minVersion> -->
                                <initialHeapSize>256</initialHeapSize>
                                <maxHeapSize>3000</maxHeapSize>
                                <!-- <minVersion>1.7.0</minVersion> -->
                                <!-- <minVersion>1.6.0</minVersion> -->
                                <!-- <jdkPreference>preferJre</jdkPreference> -->
                            </jre>
                            <versionInfo>
                                <fileVersion>1.0.0.0</fileVersion>
                                <txtFileVersion>${project.version}</txtFileVersion>
                                <fileDescription>${project.name}</fileDescription>
                                <copyright>2021 XXX.com</copyright>
                                <productVersion>1.0.0.0</productVersion>
                                <txtProductVersion>1.0.0.0</txtProductVersion>
                                <productName>${project.name}</productName>
                                <companyName>XXX.com</companyName>
                                <internalName>rfrcscheduler</internalName>
                                <originalFilename>test.exe</originalFilename>
                            </versionInfo>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

</project>

Solution

  • ok after some more searching on the stackoverflow itself I have found the answer from the below post. Launch4J Plugin creates an EXE (along with JAR) but EXE cannot find main class in Spring boot

    The issue was the generated "test.exe" could not find the main class and the answer is it should not be pointed towards the main class instead it should look for the jar launcher class

    I have updated the maven plugin <classPath> tag as suggested in the post and it worked like a charm. I hope this helps.

    <classPath>
        <mainClass>org.springframework.boot.loader.JarLauncher</mainClass>
        <addDependencies>true</addDependencies>
        <preCp>anything</preCp>
    </classPath>