Keywords: Spring Boot | Maven | ClassNotFoundException | Dependency Management | Executable JAR
Abstract: This article provides an in-depth analysis of the ClassNotFoundException error that occurs during Maven builds of Spring Boot applications, focusing on the root cause of dependency packages not being correctly packaged into executable JARs. Through detailed examination of Maven's dependency management mechanism and Spring Boot plugin configuration methods, it offers comprehensive solutions and best practices. The article includes specific code examples and step-by-step guidance for developers to properly configure pom.xml files, ensuring all runtime dependencies are correctly included in the final executable JAR to completely resolve class loading issues.
Problem Background and Error Analysis
During Spring Boot application development, developers frequently encounter a typical runtime error: java.lang.ClassNotFoundException: org.springframework.boot.SpringApplication. This error usually occurs after building the project with Maven and running the generated JAR file using the java -jar command. From the error stack trace, it's evident that while compilation proceeds without errors, the JVM cannot find essential Spring Boot core classes during runtime.
Root Cause Investigation
The core of this issue lies in Maven's default packaging mechanism. Standard Maven JAR packaging only includes the project's own compiled class files and does not package third-party dependencies into the final JAR file. When using the java -jar command, the JVM can only access classes within the JAR package and cannot access dependency libraries in the Maven local repository.
In the provided pom.xml configuration, although Spring Boot related dependencies are included:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>0.5.0.M6</version>
</dependency>
These dependencies are only downloaded to the local repository during the build process and are not included in the final executable JAR. This explains why the application runs correctly in the IDE but throws class not found errors when running the JAR file via command line.
Solution: Using Spring Boot Maven Plugin
Spring Boot provides a dedicated Maven plugin to address this issue. This plugin can create a "fat JAR" or "uber JAR" that packages all dependent class files into the same JAR file.
The correct pom.xml configuration should include the following plugin configuration:
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.7.0</version>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
Detailed Plugin Working Mechanism
The repackage goal of the Spring Boot Maven plugin executes after Maven's package phase and performs the following operations:
- Reads the original JAR file generated by standard Maven build
- Scans all project dependencies (including transitive dependencies)
- Extracts and repackages these dependency class files into a new JAR file
- Sets the correct main class manifest attribute
- Generates an executable JAR containing all necessary dependencies
This process can be verified using the following Maven command:
mvn clean package spring-boot:repackage
Complete pom.xml Configuration Example
Below is a complete, correct pom.xml configuration example for a Spring Boot project:
<?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
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>spring-boot-demo</artifactId>
<version>1.0.0</version>
<packaging>jar</packaging>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.0</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
Build and Run Verification
After configuration, execute the following command to build the project:
mvn clean package
After successful build, two JAR files will be generated in the target directory:
spring-boot-demo-1.0.0.jar- Original JAR (without dependencies)spring-boot-demo-1.0.0.jar.original- Spring Boot repackaged executable JAR
Now run the executable JAR:
java -jar target/spring-boot-demo-1.0.0.jar
The application should start normally without any ClassNotFoundException errors.
Other Potential Causes and Solutions
Besides the main dependency packaging issue, there are other scenarios that might cause similar errors:
1. Corrupted Maven Repository
As mentioned in reference answer 4, a corrupted local Maven repository might cause incomplete dependency downloads. The solution is to clean the local repository:
rm -rf ~/.m2/repository
Then re-execute the Maven build command.
2. Version Compatibility Issues
Compatibility problems between different Spring Boot versions can also cause class not found errors. Ensure all Spring-related dependencies use compatible versions.
3. Incorrect Dependency Scope Configuration
Check dependency scope configurations to ensure runtime-required dependencies are not set to provided or test scope.
Best Practice Recommendations
To avoid similar class not found issues, follow these best practices:
- Always use Spring Boot Parent POM to manage dependency versions
- Explicitly configure Spring Boot Maven plugin in pom.xml
- Regularly clean and update local Maven repository
- Validate executable JAR integrity in CI/CD pipelines
- Use Spring Boot's BOM (Bill of Materials) to ensure dependency version consistency
Conclusion
The root cause of the java.lang.ClassNotFoundException: org.springframework.boot.SpringApplication error is that dependencies are not correctly packaged into the executable JAR. By properly configuring the Spring Boot Maven plugin, you can create a "fat JAR" containing all necessary dependencies, completely resolving this issue. Understanding Maven's dependency management mechanism and Spring Boot plugin packaging principles is crucial for developing and deploying Spring Boot applications.