多模块构建中Quarkus扩展构建失败问题排查
Quarkus扩展单体仓库迁移构建失败问题排查与解决
我们正在将Quarkus扩展迁移至单体Maven仓库,本地出现随机构建失败,CI环境则呈现确定性失败。
Maven项目结构
pom.xml - library-a-parent -- library-a-runtime -- library-a-deployment - library-b-parent -- library-b-runtime -- library-b-deployment - library-c
依赖关系
- library-b依赖library-a
- library-c依赖library-b
构建现象
- 不含library-c时,构建完全正常
- 调整根pom的模块顺序可正常构建:
正常顺序的模块配置:<module>library-a-parent</module> <module>library-b-parent</module> <module>library-c</module> - 错误顺序的模块配置会导致构建失败:
<module>library-c</module> <module>library-a-parent</module> <module>library-b-parent</module>
由于待迁移库数量较多,逐个调整模块顺序的方案不可行。
错误信息
异常发生在测试执行阶段,核心表现为Quarkus尝试下载尚未构建的POM文件,手动添加依赖会导致循环依赖。完整堆栈如下:
java.lang.RuntimeException: io.quarkus.bootstrap.BootstrapException: Failed to create the application model for ch.anon.libs:lib-config-cache::jar:999-SNAPSHOTnull at io.quarkus.test.junit.QuarkusTestExtension.throwBootFailureException(QuarkusTestExtension.java:638) at io.quarkus.test.junit.QuarkusTestExtension.interceptTestClassConstructor(QuarkusTestExtension.java:722) at java.base/java.util.Optional.orElseGet(Optional.java:364) at java.base/java.util.ArrayList.forEach(ArrayList.java:1511) at java.base/java.util.ArrayList.forEach(ArrayList.java:1511) Caused by: io.quarkus.bootstrap.BootstrapException: Failed to create the application model for ch.anon.libs:lib-config-cache::jar:999-SNAPSHOTnull at io.quarkus.bootstrap.BootstrapAppModelFactory.resolveAppModel(BootstrapAppModelFactory.java:297) at io.quarkus.bootstrap.app.QuarkusBootstrap.bootstrap(QuarkusBootstrap.java:133) at io.quarkus.test.junit.AbstractJvmQuarkusTestExtension.createAugmentor(AbstractJvmQuarkusTestExtension.java:189) at io.quarkus.test.junit.QuarkusTestExtension.doJavaStart(QuarkusTestExtension.java:219) at io.quarkus.test.junit.QuarkusTestExtension.ensureStarted(QuarkusTestExtension.java:605) at io.quarkus.test.junit.QuarkusTestExtension.beforeAll(QuarkusTestExtension.java:655) ... 1 more Caused by: io.quarkus.bootstrap.resolver.AppModelResolverException: Failed to inject extension deployment dependencies for ch.anon.libs:lib-config-cache:999-SNAPSHOT at io.quarkus.bootstrap.resolver.BootstrapAppModelResolver.buildAppModel(BootstrapAppModelResolver.java:340) at io.quarkus.bootstrap.resolver.BootstrapAppModelResolver.doResolveModel(BootstrapAppModelResolver.java:288) at io.quarkus.bootstrap.resolver.BootstrapAppModelResolver.resolveManagedModel(BootstrapAppModelResolver.java:168) at io.quarkus.bootstrap.BootstrapAppModelFactory.resolveAppModel(BootstrapAppModelFactory.java:283) ... 6 more Caused by: io.quarkus.bootstrap.BootstrapDependencyProcessingException: Failed to collect dependencies of ch.anon.libs:lib-mandant-cache-deployment:jar:999-SNAPSHOT: either its POM could not be resolved from the available Maven repositories or the artifact does not have any dependencies while at least a dependency on the runtime artifact ch.anon.libs:lib-mandant-cache:jar:999-SNAPSHOT is expected at io.quarkus.bootstrap.resolver.maven.ApplicationDependencyTreeResolver.injectDeploymentDependencies(ApplicationDependencyTreeResolver.java:587) at io.quarkus.bootstrap.resolver.maven.ApplicationDependencyTreeResolver.resolve(ApplicationDependencyTreeResolver.java:207) at io.quarkus.bootstrap.resolver.BootstrapAppModelResolver.buildAppModel(BootstrapAppModelResolver.java:337)
问题根源
Maven默认按模块声明顺序执行构建,但Quarkus测试运行时需要解析所有依赖的扩展部署模块。当先构建library-c时,它依赖的library-b及其依赖的library-a还未构建安装到本地仓库,Quarkus的bootstrap机制会尝试从远程仓库拉取这些SNAPSHOT依赖,而这些依赖仅存在于本地构建流程中,因此解析失败。
解决方案
方案1:使用Maven reactor自动排序构建顺序
Maven支持根据模块依赖关系自动排序构建顺序,无需手动调整模块声明。执行构建时添加以下参数:
mvn clean install -Dreactor.sortProjects=true
该参数会让Maven自动分析模块间依赖,按正确顺序(先library-a,再library-b,最后library-c)执行构建,彻底解决顺序问题。
方案2:根pom配置dependencyManagement统一管理依赖
在根pom的dependencyManagement中声明所有模块版本,确保Quarkus解析依赖时能正确识别本地模块,避免尝试从远程仓库拉取。示例配置:
<dependencyManagement> <dependencies> <dependency> <groupId>ch.anon.libs</groupId> <artifactId>library-a-parent</artifactId> <version>999-SNAPSHOT</version> <type>pom</type> <scope>import</scope> </dependency> <dependency> <groupId>ch.anon.libs</groupId> <artifactId>library-b-parent</artifactId> <version>999-SNAPSHOT</version> <type>pom</type> <scope>import</scope> </dependency> <dependency> <groupId>ch.anon.libs</groupId> <artifactId>library-c</artifactId> <version>999-SNAPSHOT</version> </dependency> </dependencies> </dependencyManagement>
方案3:临时跳过测试(仅应急用)
如果需要临时绕过测试阶段的问题,可执行构建时跳过测试:
mvn clean install -DskipTests
此为临时方案,测试阶段仍需依赖正确解析,建议优先使用方案1或2。
内容的提问来源于stack exchange,提问作者Daniel
相关产品推荐
相关产品推荐

