Quarkus运行时自动重编译失败:自定义注解处理器引发错误
解决Quarkus开发模式热重载时自定义注解处理器构造异常问题
问题现象
初始Maven构建后应用运行正常,但在Quarkus开发模式下修改源代码触发自动重新编译时,出现如下编译错误,必须重启应用才能恢复:
Compilation Failed: Note: Annotation processing is enabled because one or more processors were found on the class path. A future release of javac may disable annotation processing unless at least one processor is specified by name (-processor), or a search path is specified (--processor-path, --processor-module-path), or annotation processing is enabled explicitly (-proc:only, -proc:full). Use -Xlint:-options to suppress this message. Use -proc:none to disable annotation processing. error: Bad service configuration file, or exception thrown while constructing Processor object: javax.annotation.processing.Processor: mycompany.package.processors.MyProcessor Unable to get public no-arg constructor
问题原因
核心问题是Quarkus开发模式的热重载编译流程中,自定义注解处理器的类加载上下文与初始构建不一致:
- 主模块同时在常规依赖和
annotationProcessorPaths中引入了处理器模块,导致处理器类同时存在于运行类路径和编译类路径 - 热重载时,Quarkus可能从运行类路径加载处理器类,而该类已被应用类加载器加载过,无法重新实例化(即使存在无参构造)
- AutoService生成的服务配置文件在热重载时被重复扫描,引发类加载冲突
解决方案
1. 调整处理器依赖的作用域为provided
修改主模块中处理器的依赖配置,将其作用域设为provided,确保处理器类仅在编译阶段可用,不会进入运行类路径:
<dependencies> [...] <dependency> <groupId>mycompany.package</groupId> <artifactId>processors</artifactId> <version>${project.parent.version}</version> <scope>provided</scope> </dependency> </dependencies>
annotationProcessorPaths中的配置保持不变,这样编译阶段仍能正确找到处理器,而运行时不会加载处理器类,避免类加载冲突。
2. 明确指定Quarkus热重载时的注解处理器
在application.properties中添加编译参数,强制指定要使用的注解处理器,避免自动扫描类路径引发的问题:
quarkus.compiler.args=-processor mycompany.package.processors.MyProcessor
3. 确保AutoService生成的服务配置正确
检查处理器模块的Maven配置,确保AutoService注解被正确处理,生成有效的服务配置文件:
在处理器模块的pom.xml中添加:
<build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <annotationProcessorPaths> <path> <groupId>com.google.auto.service</groupId> <artifactId>auto-service</artifactId> <version>1.0.1</version> </path> </annotationProcessorPaths> </configuration> </plugin> </plugins> </build>
重新构建处理器模块,确认META-INF/services/javax.annotation.processing.Processor文件中包含正确的处理器类全限定名。
4. 临时禁用增量编译(备选)
如果上述方案无效,可尝试禁用Quarkus的增量编译,强制每次热重载时全量编译:
quarkus.compiler.incremental=false
注意:此方案会降低热重载速度,仅作为临时排查手段。
内容的提问来源于stack exchange,提问作者Gwennhael
相关产品推荐
相关产品推荐

