使用ECJ编译器的Gradle注解处理器报无法获取无参公共构造方法错误
解决ECJ编译Gradle项目时注解处理器的ServiceConfigurationError问题
尝试用ECJ编译器编译包含注解处理器(被其他项目依赖)的Gradle项目时,出现如下错误:
1. ERROR in C:\...\MyClass.java (at line 0) package my.package; ^ Internal compiler error: java.util.ServiceConfigurationError: javax.annotation.processing.Processor: my.AnnotationProcessor Unable to get public no-arg constructor at java.base/java.util.ServiceLoader.fail(ServiceLoader.java:582)已尝试给注解处理器添加公共无参构造方法,也在命令行参数中加入
--add-opens java.base/java.util=ALL-UNNAMED,但问题仍未解决。当前Gradle配置如下:configurations { ecj } dependencies { ecj 'org.eclipse.jdt:ecj:3.25.0' } tasks.withType(JavaCompile) { options.headerOutputDirectory.convention(null) //To stop gradle from passing in -h, which ecj doesn't recognize } compileJava { options.fork = true options.forkOptions.with { executable = 'java' jvmArgs = ['-classpath', project.configurations.ecj.asPath, '--add-opens', 'java.base/java.util=ALL-UNNAMED', 'org.eclipse.jdt.internal.compiler.batch.Main'] } }
可行的解决方法
1. 把注解处理器加入ECJ的类路径
当前配置里ECJ的classpath只包含自身,注解处理器及其依赖没被加载到ECJ进程中,这是ServiceLoader找不到类的核心原因。修改compileJava的配置,合并ECJ和注解处理器的classpath:
compileJava { options.fork = true options.forkOptions.with { executable = 'java' // 合并ECJ、注解处理器及依赖的类路径 def combinedClasspath = [ project.configurations.ecj.asPath, project.configurations.annotationProcessor.asPath, // 如果注解处理器是内部模块,加上模块的编译输出目录 project(':processor-module').sourceSets.main.output.classesDirs.asPath ].join(File.pathSeparator) jvmArgs = [ '-classpath', combinedClasspath, '--add-opens', 'java.base/java.util=ALL-UNNAMED', 'org.eclipse.jdt.internal.compiler.batch.Main' ] } }
2. 补充反射相关的JVM参数
Java 9+模块化环境下,获取构造方法需要额外的反射权限,添加以下参数到jvmArgs中:
jvmArgs = [ '-classpath', combinedClasspath, '--add-opens', 'java.base/java.util=ALL-UNNAMED', '--add-opens', 'java.base/java.lang.reflect=ALL-UNNAMED', // 允许反射访问构造方法 '--add-exports', 'javax.annotation.processing=ALL-UNNAMED', // 导出注解处理API 'org.eclipse.jdt.internal.compiler.batch.Main' ]
3. 校验ServiceLoader配置文件
确认注解处理器的资源目录下存在META-INF/services/javax.annotation.processing.Processor文件,文件内容准确为my.AnnotationProcessor,无拼写错误、多余空格或换行。
4. 升级ECJ版本
ECJ 3.25.0对高版本Java的兼容性可能不足,尝试升级到最新稳定版,比如org.eclipse.jdt:ecj:3.36.0,更新依赖后重新编译测试。
内容的提问来源于stack exchange,提问作者user1428945
相关产品推荐
相关产品推荐

