Keywords: Maven Multi-module | Spring Boot | pluginManagement | Build Error | Eclipse Integration
Abstract: This article provides an in-depth analysis of the "Unable to find main class" error encountered when building multi-module Spring Boot projects with Maven in Eclipse. By examining project structure, Maven plugin configuration, and Spring Boot packaging mechanisms, it identifies the root cause as improper configuration of spring-boot-maven-plugin in modules lacking main classes. The article presents a solution based on pluginManagement, supported by code examples and configuration comparisons to help developers understand proper build practices for Maven multi-module projects.
Problem Background and Error Analysis
In Maven multi-module Spring Boot projects, developers frequently encounter the "Unable to find main class" build error. This error typically occurs after project refactoring or dependency adjustments, particularly when the project contains multiple modules and some modules do not include executable main classes.
From the error stack trace, we can see that the problem occurs during the execution of the spring-boot-maven-plugin's repackage goal. This plugin attempts to repackage each module but cannot find a suitable entry point in modules without main classes, resulting in build failure.
Maven Multi-module Project Structure Analysis
Typical Maven multi-module projects employ a parent-child structure, where the parent module uses <packaging>pom</packaging> and child modules are declared via the <modules> element. In Spring Boot projects, usually only specific application modules contain main classes annotated with @SpringBootApplication, while other modules such as utility classes and common components may lack executable entry points.
Below is an example of a typical multi-module project structure:
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>multi-module-parent</artifactId>
<version>1.0.0</version>
<packaging>pom</packaging>
<modules>
<module>core-module</module>
<module>util-module</module>
<module>web-app-module</module>
</modules>
</project>
Spring Boot Maven Plugin Mechanism
The spring-boot-maven-plugin is a core build plugin for Spring Boot projects, providing the following main functionalities:
- repackage: Repackages the generated JAR file to make it an executable Spring Boot JAR
- run: Runs the Spring Boot application
- build-info: Generates build information files
When the plugin executes in modules containing main classes, it performs the following actions:
- Scans the classpath for classes annotated with
@SpringBootApplication - Creates an executable JAR file structure
- Embeds necessary dependencies and startup scripts
However, in modules without main classes, the plugin cannot complete these operations, leading to build failure.
Solution: Using pluginManagement
The most effective solution involves using <pluginManagement> in the parent POM to manage the spring-boot-maven-plugin, then explicitly declaring it in child modules that require the plugin.
Parent POM Configuration Example:
<project>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring.boot.version}</version>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
Application Module POM Configuration:
<project>
<artifactId>web-app-module</artifactId>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
Alternative Solution Analysis
Beyond the primary pluginManagement approach, several other handling methods exist:
Option 1: Skip Repackaging for Non-application Modules
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
This method is suitable for scenarios where the plugin needs to be declared in all modules but repackaging should be skipped for certain modules.
Option 2: Explicitly Specify Main Class
<properties>
<start-class>com.example.Application</start-class>
</properties>
When the plugin cannot automatically detect the main class, the entry point can be explicitly specified.
Option 3: Remove Plugin Declaration from Unnecessary Modules
The simplest approach is to remove the spring-boot-maven-plugin declaration directly from modules that do not require repackaging.
Best Practice Recommendations
Based on practical project experience, we recommend the following best practices:
- Clear Module Responsibility Division: Ensure each module has a clear responsibility, with only application modules containing executable entry points
- Unified Plugin Management: Use
pluginManagementto centrally manage all plugin versions and configurations - Selective Plugin Application: Enable
spring-boot-maven-pluginonly in modules requiring repackaging - Continuous Integration Validation: Verify multi-module build correctness in CI/CD pipelines
System Design Considerations
In multi-module project design, proper architectural planning is crucial. Through modular design, we can achieve:
- Separation of Concerns: Different modules handle different business domains
- Dependency Management: Clear dependency relationships avoid circular dependencies
- Build Optimization: Parallel builds and incremental compilation improve development efficiency
- Deployment Flexibility: Support independent deployment and version management of modules
This design pattern not only resolves current build issues but also establishes a solid foundation for long-term project maintenance and expansion.