SpringBoot多模块项目Common模块POI依赖无法传递至兄弟服务
问题:SpringBoot多模块项目中POI依赖传递失效导致ClassNotFoundException
项目环境与结构
- SpringBoot 3.4.x + Java 21
- 多模块结构:
project-name - common-module (JAR包,包含Excel导出工具类,依赖POI) - app-service-one (SpringBoot服务模块,依赖common-module) - app-service-two
问题现象
调用app-service-one中TestController的API,触发common-module的Excel导出功能时,抛出以下异常:
java.lang.ClassNotFoundException: org.apache.poi.ss.usermodel.IndexedColors at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641) ~[na:na] at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188) ~[na:na] at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:526) ~[na:na] at com.org.org.common.core.lib.export.DesignOption.<init>(DesignOption.java:8) ~[classes/:na]
单独在app-service-one中添加POI依赖可正常运行,但希望避免在多个服务模块中重复配置依赖。
相关文件内容
common-module/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 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>com.org.dashboard</groupId> <artifactId>dashboard-service</artifactId> <version>1.0.0</version> </parent> <artifactId>common-sdk</artifactId> <packaging>jar</packaging> <properties> <java.version>21</java.version> <mapstruct.version>1.5.5.Final</mapstruct.version> <lombok.version>1.18.30</lombok.version> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <dependencies> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>6.2.2</version> <!-- Match the version used in your Spring Boot services --> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>5.2.3</version> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</artifactId> <version>5.2.3</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>6.2.2</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <version>${spring-boot.version}</version> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.11.0</version> <configuration> <source>${java.version}</source> <target>${java.version}</target> </configuration> </plugin> </plugins> </build> </project>
service-one/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 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>com.org.dashboard</groupId> <artifactId>dashboard-service</artifactId> <version>1.0.0</version> </parent> <artifactId>service-one</artifactId> <properties> <maven.compiler.source>21</maven.compiler.source> <maven.compiler.target>21</maven.compiler.target> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>com.org.dashboard</groupId> <artifactId>common-sdk</artifactId> <version>1.0.0</version> </dependency> </dependencies> <build> <plugins> <!-- Spring Boot Maven Plugin --> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <version>${spring-boot.version}</version> </plugin> <!-- Maven Compiler Plugin --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.11.0</version> <configuration> <source>${java.version}</source> <target>${java.version}</target> </configuration> </plugin> </plugins> </build> </project>
相关Java代码
import lombok.AllArgsConstructor; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; import org.apache.poi.ss.usermodel.IndexedColors; @EqualsAndHashCode(callSuper = true) @Data @AllArgsConstructor @NoArgsConstructor public class ExcelDesignOption extends DesignOption { private short headerBackgroundColor = IndexedColors.GREY_25_PERCENT.getIndex(); private short alternateRowBackgroundColor = IndexedColors.LIGHT_YELLOW.getIndex(); }
Parent/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 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.org.dashboard</groupId> <artifactId>dashboard-service</artifactId> <version>1.0.0</version> <packaging>pom</packaging> <modules> <module>common-sdk</module> <module>one-service</module> <module>two-service</module> </modules> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>3.4.1</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <properties> <java.version>21</java.version> <spring-boot.version>3.4.1</spring-boot.version> </properties> <dependencies> <!-- Add shared dependencies here --> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.30</version> <scope>provided</scope> </dependency> </dependencies> </project>
问题原因与解决方案
核心原因
common-module中错误使用了spring-boot-maven-plugin,该插件默认会将模块打包成可执行JAR,并且不会包含依赖的传递性JAR包,导致service-one依赖common-module时,无法获取POI相关依赖。
解决步骤
- 移除common-module中的spring-boot-maven-plugin
common-module是普通JAR模块,不需要Spring Boot的可执行打包插件,修改common-module/pom.xml的build部分:<build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.11.0</version> <configuration> <source>${java.version}</source> <target>${java.version}</target> </configuration> </plugin> </plugins> </build> - 清理并重新构建项目
执行Maven命令:mvn clean install -DskipTests - 验证依赖传递
在service-one模块中执行mmvn dependency:tree,确认POI相关依赖已通过common-sdk传递过来。
额外优化建议
- 避免在common-module中手动指定Spring框架版本(如spring-core 6.2.2),通过父pom的Spring Boot依赖管理自动继承版本,防止版本冲突。
- 移除service-one中重复的
spring-boot-starter-web依赖。
内容的提问来源于stack exchange,提问作者Dnyaneshwar Jadhav
相关产品推荐
相关产品推荐

