You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring项目Gradle构建时QClass重复生成报错求助

Gradle构建Jar时QueryDSL QClass重复生成错误的解决方法

问题背景

开发环境:

  • IntelliJ 2022.3.2
  • Gradle 7.6
  • Spring Boot 3.0.3
  • QueryDSL 5.0.0(Jakarta兼容版)

当前build.gradle配置:

plugins {
    id 'java'
    id 'org.springframework.boot' version '3.0.3'
    id 'io.spring.dependency-management' version '1.1.0'
    id "com.ewerk.gradle.plugins.querydsl" version "1.0.10"
}

group = 'heyuniverse'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '17'

configurations {
    compileOnly {
        extendsFrom annotationProcessor
    }
    querydsl.extendsFrom compileClasspath
}

repositories {
    mavenCentral()
}

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
    implementation 'org.springframework.boot:spring-boot-starter-security'
    implementation 'org.springframework.boot:spring-boot-starter-web'
//    implementation 'ch.pete.appconfig:appconfig:0.1.0'
    compileOnly 'org.projectlombok:lombok'
    runtimeOnly 'com.mysql:mysql-connector-j'
    annotationProcessor 'org.projectlombok:lombok'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
    testImplementation 'org.springframework.security:spring-security-test'
    implementation group: 'org.javassist', name: 'javassist', version: '3.15.0-GA'
    // === QueryDsl
    implementation 'com.querydsl:querydsl-jpa:5.0.0:jakarta'
    annotationProcessor "com.querydsl:querydsl-apt:${dependencyManagement.importedProperties['querydsl.version']}:jakarta"
//    annotationProcessor 'com.querydsl:querydsl-apt:5.0.0:jakarta'
    annotationProcessor "jakarta.persistence:jakarta.persistence-api"
    annotationProcessor "jakarta.annotation:jakarta.annotation-api"
    //JWT
    implementation group: 'io.jsonwebtoken', name: 'jjwt-api', version: '0.11.2'
    runtimeOnly group: 'io.jsonwebtoken', name: 'jjwt-impl', version: '0.11.2'
    runtimeOnly group: 'io.jsonwebtoken', name: 'jjwt-jackson', version: '0.11.2'
}

tasks.named('test') {
    useJUnitPlatform()
}

def querydslDir = "$buildDir/generated/querydsl"
clean {
    delete file("build/generated")
}

querydsl {
    library = "com.querydsl:querydsl-apt"
    jpa = true
    querydslSourcesDir = querydslDir
}

sourceSets {
    main.java.srcDir querydslDir
}

compileQuerydsl {
    options.annotationProcessorPath = configurations.querydsl
}

错误现象

单独执行compileQuerydsl可正常生成QClass并运行,但执行gradle build生成Jar包时,触发编译错误:

FAILURE: Build failed with an exception.
What went wrong:
Execution failed for task ':compileJava'.
Compilation failed; see the compiler error output for details.
Try:
Run with --stacktrace option to get the stack trace.
Run with --info or --debug option to get more log output.
Run with --scan to get full insights.
Get more help at https://help.gradle.org
BUILD FAILED in 4s
error: Attempt to recreate a file for type xxx.xxx.QClass
error: Attempt to recreate a file for type xxx.xxx.QClass
error: Attempt to recreate a file for type xxx.xxx.QClass
error: Attempt to recreate a file for type xxx.xxx.QClass

原因分析

  1. 注解处理器重复执行:QueryDSL的APT同时被加入了annotationProcessor全局配置和querydsl插件配置,导致compileJava任务和compileQuerydsl任务都会触发QClass生成,生成相同文件引发冲突。
  2. 源码集配置冲突:将querydslDir加入主源码集后,compileJava会同时编译原生源码和已生成的QClass,加上APT的重复生成,进一步加剧文件重复问题。

解决方案

1. 隔离QueryDSL APT的作用范围

将QueryDSL的APT依赖从全局annotationProcessor移至querydsl专属配置,确保仅compileQuerydsl任务触发QClass生成:

// 修改dependencies中的QueryDSL部分:
dependencies {
    // ... 其他依赖保持不变 ...
    // === QueryDsl
    implementation 'com.querydsl:querydsl-jpa:5.0.0:jakarta'
    // 移除annotationProcessor配置,改用querydsl配置
    querydsl "com.querydsl:querydsl-apt:5.0.0:jakarta"
    querydsl "jakarta.persistence:jakarta.persistence-api"
    querydsl "jakarta.annotation:jakarta.annotation-api"
    // ... 其他依赖保持不变 ...
}

2. 调整任务依赖与编译范围

确保compileJava在compileQuerydsl之后执行,并排除已生成的QClass避免重复编译:

tasks.named('compileJava') {
    // 确保先执行QClass生成,再编译主源码
    dependsOn tasks.named('compileQuerydsl')
    // 排除生成目录下的QClass文件,避免重复编译
    exclude '**/Q*.java'
}

3. 优化清理任务

确保clean任务彻底清理生成目录,避免残留旧文件引发冲突:

def querydslDir = "$buildDir/generated/querydsl"
clean {
    delete fileTree(querydslDir)
    delete file("build/generated")
}

验证步骤

  1. 执行./gradlew clean彻底清理构建缓存和生成文件
  2. 执行./gradlew compileQuerydsl确认QClass正常生成到指定目录
  3. 执行./gradlew build验证Jar包构建成功

内容的提问来源于stack exchange,提问作者박민규

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 06:12:02