Search code examples
javaspringmavenintellij-ideadeployment

Maven: Cannot find or load main class


I made my first Spring application and now I need to package it in a jar file for deployment. Inside pom.xml, I specified the maven-jar-plugin in order to automatically create the manifest file for my jar, like this:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-jar-plugin</artifactId>
    <version>3.3.0</version>
    <configuration>
        <archive>
            <manifest>
                <mainClass>bg.sofia.uni.fmi.melodify.MelodifyApplication</mainClass>
            </manifest>
        </archive>
    </configuration>
</plugin>

Then I package it using the package button inside the Intellij Maven view and it produces a jar file successfully. When I run the jar file with java -jar <path/to/jar/file.jar>, I get the following error:

Error: Could not find or load main class bg.sofia.uni.fmi.melodify.MelodifyApplication
Caused by: java.lang.NoClassDefFoundError: org/springframework/boot/CommandLineRunner

My MelodifyApplication class looks like this:

@SpringBootApplication
public class MelodifyApplication implements CommandLineRunner {

    public static void main(String[] args) {
        SpringApplication.run(MelodifyApplication.class, args);
    }

    @Override
    public void run(String... args) throws Exception {
        System.out.println("Application started ...");
    }
}

I tried writing my own Manifest.mf file and creating the jar myself like this:

jar cfm Melodify.jar Manifest.mf -C Melodify/src/main/java/ .

but I got the same error. What am I doing wrong?


Solution

  • One solution is to follow the pattern what Spring Initializr does:

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.2.1</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    

    Optional: Defining the spring-boot-starter-parent makes your life easier - it handles dependency management for you. Background: see this Question.

    Finally, instead of Maven Jar Plugin, use Spring Boot Maven Plugin:

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
    

    With this setup, issuing:

    mvn package
    

    ...should build you a proper uber-jar of your Spring Application:

    java -jar target/spring-sandbox-0.0.1-SNAPSHOT.jar
    
      .   ____          _            __ _ _
     /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
    ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
     \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
      '  |____| .__|_| |_|_| |_\__, | / / / /
     =========|_|==============|___/=/_/_/_/
     :: Spring Boot ::                (v3.2.1)
    
    2024-01-10T09:52:00.671+01:00  INFO 98109 --- [           main] c.g.t.s.SpringSandboxApplication         : Starting SpringSandboxApplication using Java 17.0.3 with PID 98109 (/Users/tamas/git/spring-sandbox/target/spring-sandbox-0.0.1-SNAPSHOT.jar started by tamas in /Users/tamas/git/spring-sandbox)
    ...