使用Maven构建SpringBoot应用时本地Jar依赖报Cannot find symbol错误
问题场景
用Maven构建SpringBoot应用,本地仓库有个需要引入的Jar包,通过maven-install-plugin能成功安装,但执行mvn compile时触发Cannot find symbol错误,找不到Jar里的Authenticator类,报错出现在导入语句处,且IDE里完全正常。所有构建操作在Docker中执行,保证部署一致性。
相关信息
构建指令
mvn clean mvn org.apache.maven.plugins:maven-install-plugin:2.5.2:install-file -Dfile=./repo/gov/nasa/drf/lib/lib-1.0.jar -DgroupId=gov.nasa.drf -DartifactId=lib -Dversion=1.0 -Dpackaging=jar mvn compile mvn package
错误信息
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.11.0:compile (default-compile) on project auth: Compilation failure [ERROR] /buildDir/src/main/java/gov/nasa/drf/auth/accesscontrol/AuthenticationAspect.java:[3,38] cannot find symbol [ERROR] symbol: class Authenticator [ERROR] location: package gov.nasa.drf.lib.accesscontrol
Dockerfile
FROM maven:3-openjdk-17 AS build COPY ./src /buildDir/src COPY ./repo /buildDir/repo COPY pom.xml /buildDir/pom.xml WORKDIR /buildDir RUN mvn clean RUN mvn org.apache.maven.plugins:maven-install-plugin:2.5.2:install-file -Dfile=./repo/gov/nasa/drf/lib/lib-1.0.jar -DgroupId="gov.nasa.drf" -DartifactId="lib" -Dversion="1.0" -Dpackaging=jar RUN mvn compile RUN mvn package FROM openjdk:17-oracle RUN mkdir -p /api/target RUN mkdir -p /api/src/main RUN mkdir /api/keys RUN mkdir /api/logs COPY src/main/resources /api/src/main/resources COPY --from=build /buildDir/target /api/target COPY pom.xml /api/pom.xml WORKDIR /api EXPOSE 8082 CMD ["java", "-jar", "/api/target/auth-2.0.jar"]
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>gov.nasa.drf</groupId> <artifactId>auth</artifactId> <version>2.0</version> <properties> <maven.compiler.source>17</maven.compiler.source> <maven.compiler.target>17</maven.compiler.target> <spring.version>6.1.0.RELEASE</spring.version> <aspectj.version>1.9.19</aspectj.version> <log4j2.version>2.17.1</log4j2.version> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>3.1.1</version> </parent> <repositories> <repository> <id>data-local</id> <name>data</name> <url>file://${project.basedir}/repo</url> </repository> </repositories> <build> <sourceDirectory>src/main/java</sourceDirectory> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-jar-plugin</artifactId> <configuration> <archive> <manifest> <addClasspath>true</addClasspath> <classpathPrefix>lib/</classpathPrefix> <mainClass>gov.nasa.drf.auth.App</mainClass> </manifest> </archive> </configuration> </plugin> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <executions> <execution> <goals> <goal>repackage</goal> </goals> </execution> </executions> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <version>3.1.2</version> <dependencies> <dependency> <groupId>org.apache.maven.surefire</groupId> <artifactId>surefire-junit47</artifactId> <version>3.1.2</version> </dependency> </dependencies> <configuration> <parallel>both</parallel> <threadCount>4</threadCount> <includes> <include>**/*Test</include> </includes> </configuration> </plugin> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>aspectj-maven-plugin</artifactId> <version>1.14.0</version> <dependencies> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjrt</artifactId> <version>${aspectj.version}</version> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjtools</artifactId> <version>${aspectj.version}</version> </dependency> </dependencies> <executions> <execution> <goals> <goal>compile</goal> <goal>test-compile</goal> </goals> </execution> </executions> <configuration> <outxml>true</outxml> <verbose>true</verbose> <showWeaveInfo>true</showWeaveInfo> <aspectLibraries> <aspectLibrary> <groupId>org.springframework</groupId> <artifactId>spring-aspects</artifactId> </aspectLibrary> </aspectLibraries> <source>17</source> <target>17</target> </configuration> </plugin> </plugins> </build> <dependencies> <dependency> <groupId>gov.nasa.drf</groupId> <artifactId>lib</artifactId> <version>1.0</version> </dependency> <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>javax.persistence</groupId> <artifactId>javax.persistence-api</artifactId> <version>2.2</version> </dependency> <dependency> <groupId>org.springdoc</groupId> <artifactId>springdoc-openapi-starter-webmvc-ui</artifactId> <version>2.0.2</version> </dependency> <dependency> <groupId>com.github.joschi.jackson</groupId> <artifactId>jackson-datatype-threetenbp</artifactId> <version>2.13.0-rc2</version> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.28</version> <scope>provided</scope> </dependency> <dependency> <groupId>org.postgresql</groupId> <artifactId>postgresql</artifactId> <version>42.6.0</version> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjrt</artifactId> <version>${aspectj.version}</version> <scope>runtime</scope> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjtools</artifactId> <version>${aspectj.version}</version> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>${aspectj.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aop</artifactId> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aspects</artifactId> </dependency> </dependencies> </project>
解决步骤
1. 合并Docker中的Maven命令(优先尝试)
Docker里每个RUN指令会生成独立层,分开执行install-file和compile可能导致Maven无法识别已安装的Jar(缓存隔离问题)。把所有Maven操作合并成一个命令:
WORKDIR /buildDir RUN mvn clean \ org.apache.maven.plugins:maven-install-plugin:2.5.2:install-file -Dfile=./repo/gov/nasa/drf/lib/lib-1.0.jar -DgroupId="gov.nasa.drf" -DartifactId="lib" -Dversion="1.0" -Dpackaging=jar \ compile \ package
这样Maven在同一个进程内完成所有操作,能确保安装的Jar被后续编译阶段识别。
2. 给AspectJ编译插件添加本地Jar依赖
报错的类出现在Aspect类的导入语句中,而项目用了aspectj-maven-plugin编译,默认情况下这个插件可能没包含本地安装的Jar。修改插件配置,添加依赖:
<plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>aspectj-maven-plugin</artifactId> <version>1.14.0</version> <dependencies> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjrt</artifactId> <version>${aspectj.version}</version> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjtools</artifactId> <version>${aspectj.version}</version> </dependency> <!-- 新增本地Jar依赖 --> <dependency> <groupId>gov.nasa.drf</groupId> <artifactId>lib</artifactId> <version>1.0</version> </dependency> </dependencies> <!-- 其余配置保持不变 --> </plugin>
3. 验证Jar包结构与导入路径是否匹配
确认lib-1.0.jar里Authenticator类的实际包路径是不是gov.nasa.drf.lib.accesscontrol,可以用以下命令查看:
jar tf ./repo/gov/nasa/drf/lib/lib-1.0.jar | grep Authenticator
如果输出路径和代码导入路径不一致,要么改代码导入语句,要么确认安装Jar时的groupId/artifactId是否正确。
4. 检查Docker中Maven仓库的权限
Docker容器里安装Jar时可能没有写入默认仓库的权限,导致Jar没真正安装成功。可以指定安装到项目本地仓库:
修改install-file命令,加上-DlocalRepositoryPath=${project.basedir}/.m2/repo参数:
mvn org.apache.maven.plugins:maven-install-plugin:2.5.2:install-file -Dfile=./repo/gov/nasa/drf/lib/lib-1.0.jar -DgroupId=gov.nasa.drf -DartifactId=lib -Dversion=1.0 -Dpackaging=jar -DlocalRepositoryPath=${project.basedir}/.m2/repo
同时在pom.xml里添加这个本地仓库的配置:
<repositories> <repository> <id>data-local</id> <name>data</name> <url>file://${project.basedir}/repo</url> </repository> <repository> <id>local-m2</id> <name>Local M2 Repository</name> <url>file://${project.basedir}/.m2/repo</url> </repository> </repositories>
内容的提问来源于stack exchange,提问作者jnasworld223

