Maven父POM中类无法识别:Cannot find symbol编译错误求助
父POM中的类无法被子微服务识别的原因及解决方法
我不是Maven专家,正在搭建一个作为所有微服务父项目的框架,框架里包含各类通用与抽象类,父POM的packaging设为pom,代码如下:
<?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.7.3</version> <relativePath /> </parent> <groupId>groupId</groupId> <artifactId>artifactId</artifactId> <version>0.0.1-SNAPSHOT</version> <name>name</name> <description>description</description> <packaging>pom</packaging> <properties> <java.version>11</java.version> <maven.compiler.release>11</maven.compiler.release> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </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-data-rest</artifactId> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> <dependency> <groupId>org.springdoc</groupId> <artifactId>springdoc-openapi-ui</artifactId> <version>1.6.11</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-validation</artifactId> </dependency> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> <version>3.12.0</version> </dependency> <dependency> <groupId>org.mapstruct</groupId> <artifactId>mapstruct</artifactId> <version>1.5.2.Final</version> </dependency> </dependencies> </project>
随后创建了微服务项目,将该框架设为父POM,子项目POM代码如下:
<?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>groupId</groupId> <artifactId>artifactId</artifactId> <version>0.0.1-SNAPSHOT</version> </parent> <artifactId>Be-ms</artifactId> <version>0.0.1-SNAPSHOT</version> <name>Be-ms</name> <description>Be-ms</description> <properties> <java.version>11</java.version> <maven.compiler.release>11</maven.compiler.release> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.postgresql</groupId> <artifactId>postgresql</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-sleuth</artifactId> <version>3.1.4</version> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-sleuth-zipkin</artifactId> <version>3.1.4</version> </dependency> </dependencies> <profiles> <profile> <id>dev</id> <properties> <activatedProperties>dev</activatedProperties> </properties> </profile> <profile> <id>col</id> <activation> <activeByDefault>true</activeByDefault> </activation> <properties> <activatedProperties>col</activatedProperties> </properties> </profile> <profile> <id>prod</id> <properties> <activatedProperties>prod</activatedProperties> </properties> </profile> </profiles> </project>
但编译时出现大量cannot find symbol错误,比如找不到Generic service类,请问为何父POM中的类无法被识别?
原因分析
Maven中packaging为pom的项目是聚合/依赖管理专用项目,这类项目不会编译自身的Java代码,也不会生成可被依赖的jar包。它的核心作用是统一管理依赖版本、聚合子项目,本身不提供任何可被引用的类资源。因此子项目仅通过<parent>标签引用它时,根本无法获取父项目里的通用类。
解决方法
方案1:拆分父项目为「pom父项目」+「通用jar模块」(推荐)
这是多模块项目的标准做法,将依赖管理职责和代码提供职责分离:
- 保留原有的pom类型父项目,仅负责统一管理依赖版本、聚合所有子模块
- 新建一个
common模块(packaging设为jar),把原父项目中的通用/抽象类全部迁移到这个模块 - 所有微服务子项目通过
<dependency>标签引用这个common模块
调整后的父POM(仅做依赖管理和聚合)
<?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.7.3</version> <relativePath/> </parent> <groupId>groupId</groupId> <artifactId>artifactId</artifactId> <version>0.0.1-SNAPSHOT</version> <name>name</name> <description>description</description> <packaging>pom</packaging> <!-- 聚合所有子模块 --> <modules> <module>common</module> <module>Be-ms</module> </modules> <properties> <java.version>11</java.version> <maven.compiler.release>11</maven.compiler.release> <!-- 统一管理依赖版本,子模块无需重复写版本号 --> <springdoc.version>1.6.11</springdoc.version> <commons-lang3.version>3.12.0</commons-lang3.version> <mapstruct.version>1.5.2.Final</mapstruct.version> <spring-cloud-sleuth.version>3.1.4</spring-cloud-sleuth.version> </properties> <!-- 依赖版本管理 --> <dependencyManagement> <dependencies> <dependency> <groupId>groupId</groupId> <artifactId>common</artifactId> <version>${project.version}</version> </dependency> <dependency> <groupId>org.springdoc</groupId> <artifactId>springdoc-openapi-ui</artifactId> <version>${springdoc.version}</version> </dependency> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> <version>${commons-lang3.version}</version> </dependency> <dependency> <groupId>org.mapstruct</groupId> <artifactId>mapstruct</artifactId> <version>${mapstruct.version}</version> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-sleuth</artifactId> <version>${spring-cloud-sleuth.version}</version> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-sleuth-zipkin</artifactId> <version>${spring-cloud-sleuth.version}</version> </dependency> </dependencies> </dependencyManagement> </project>
common模块的POM(负责提供通用类)
<?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"> <parent> <groupId>groupId</groupId> <artifactId>artifactId</artifactId> <version>0.0.1-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>common</artifactId> <packaging>jar</packaging> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </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-data-rest</artifactId> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> <dependency> <groupId>org.springdoc</groupId> <artifactId>springdoc-openapi-ui</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-validation</artifactId> </dependency> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> </dependency> <dependency> <groupId>org.mapstruct</groupId> <artifactId>mapstruct</artifactId> </dependency> </dependencies> </project>
子微服务POM添加对common模块的依赖
<dependencies> <!-- 引入通用类模块 --> <dependency> <groupId>groupId</groupId> <artifactId>common</artifactId> </dependency> <!-- 原有依赖保留 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.postgresql</groupId> <artifactId>postgresql</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-sleuth</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-sleuth-zipkin</artifactId> </dependency> </dependencies>
方案2:修改父项目的packaging为jar(不推荐)
如果不想拆分项目,可以把父项目的<packaging>pom</packaging>改成<packaging>jar</packaging>,这样父项目会编译代码并生成jar包。然后子项目除了作为父项目引用外,还需要添加对父项目的依赖:
<dependencies> <dependency> <groupId>groupId</groupId> <artifactId>artifactId</artifactId> <version>${project.version}</version> </dependency> <!-- 其他依赖 --> </dependencies>
这种方式虽然简单,但会混淆父项目的职责(既是依赖管理父项目,又是提供代码的模块),长期维护容易出现版本冲突、职责不清等问题,不推荐在多模块场景使用。
内容的提问来源于stack exchange,提问作者Saverio Mirko Viola
相关产品推荐
相关产品推荐

