Java 17环境下QueryDSL QClass重复生成致Gradle构建失败求助
解决QueryDSL QClass重复生成导致的Gradle构建错误
问题原因
Attempt to recreate a file for type com.example.project.domain.QXXXXX 错误源于同一QClass文件被多个注解处理器任务重复生成。结合你使用的技术栈(Java 17、QueryDSL 5.0、Spring Boot 3.2.0、Lombok 1.18.30、Gradle 7.4.1),核心冲突点包括:
com.ewerk.gradle.plugins.querydsl插件与Spring Boot自带的注解处理任务重复触发QueryDSL的APT(注解处理器)- Lombok插件的注解处理阶段与QueryDSL任务存在执行顺序或目录重叠问题
排查验证
- 查看构建目录
build/generated/sources/,检查是否存在多个子目录(如annotationProcessor、querydsl)下生成了相同的QClass文件 - 执行
./gradlew tasks --group=QueryDSL,确认QueryDSL相关任务是否与compileJava、processResources等任务存在重复依赖
解决方案
方案一:调整QueryDSL插件配置,隔离生成任务
修改build.gradle,明确指定QueryDSL生成目录,并避免与其他注解处理器任务冲突:
plugins { id 'java' id 'org.springframework.boot' version '3.2.0' id 'io.spring.dependency-management' version '1.0.11.RELEASE' id 'com.ewerk.gradle.plugins.querydsl' version '1.0.10' id "io.freefair.lombok" version "8.4" } dependencies { // 核心QueryDSL依赖 implementation 'com.querydsl:querydsl-jpa:5.0.0' annotationProcessor 'com.querydsl:querydsl-apt:5.0.0:jpa' annotationProcessor 'jakarta.persistence:jakarta.persistence-api' annotationProcessor 'jakarta.annotation:jakarta.annotation-api' } querydsl { jpa = true // 指定独立的QClass生成目录,避免与其他注解处理器共用目录 querydslSourcesDir = file("$buildDir/generated/sources/querydsl") } // 确保compileJava任务仅依赖QueryDSL的源码生成任务 compileJava { dependsOn querydslSources source = querydsl.querydslSourcesDir options.annotationProcessorPath = configurations.annotationProcessor } // 禁用默认的注解处理器自动触发,避免重复执行 tasks.withType(JavaCompile) { options.compilerArgs += ['-proc:none'] }
方案二:移除QueryDSL插件,手动配置APT任务
如果插件兼容性问题无法解决,直接抛弃com.ewerk插件,手动配置QueryDSL的注解处理器任务:
plugins { id 'java' id 'org.springframework.boot' version '3.2.0' id 'io.spring.dependency-management' version '1.0.11.RELEASE' id "io.freefair.lombok" version "8.4" } dependencies { implementation 'com.querydsl:querydsl-jpa:5.0.0' annotationProcessor 'com.querydsl:querydsl-apt:5.0.0:jpa' annotationProcessor 'jakarta.persistence:jakarta.persistence-api' annotationProcessor 'jakarta.annotation:jakarta.annotation-api' } // 配置QueryDSL生成目录到sourceSets sourceSets { main { java { srcDirs += "$buildDir/generated/sources/querydsl" } } } // 自定义QueryDSL生成任务 task generateQuerydsl(type: JavaCompile) { source = sourceSets.main.java classpath = configurations.compileClasspath + configurations.annotationProcessorPath options.compilerArgs = [ "-proc:only", // 仅执行注解处理,不编译源码 "-processor", "com.querydsl.apt.jpa.JPAAnnotationProcessor" ] destinationDir = file("$buildDir/generated/sources/querydsl") } // 让compileJava依赖自定义的生成任务 compileJava { dependsOn generateQuerydsl source += generateQuerydsl.destinationDir }
方案三:调整Lombok与QueryDSL的执行顺序
确保Lombok先完成注解处理,再执行QueryDSL的生成任务,避免目录冲突:
lombok { annotationProcessor = true // 指定Lombok独立的生成目录 generatedSourcesDir = file("$buildDir/generated/sources/lombok") } // 让QueryDSL任务在Lombok处理后执行 querydslSources { dependsOn compileJava }
最后步骤:清理构建目录重新构建
执行以下命令彻底清理旧生成文件后重新构建:
./gradlew clean build
内容的提问来源于stack exchange,提问作者Vandit Shah
相关产品推荐
相关产品推荐

