使用官方JOOQ Gradle插件构建Micronaut 4应用编译失败
问题
我是JOOQ新手,尝试在Micronaut 4应用中使用最新发布的官方JOOQ Gradle插件。以下是我的build.gradle.kts配置:
plugins { alias(libs.plugins.shadow) alias(libs.plugins.micronaut.application) alias(libs.plugins.ons.plugin.release) alias(libs.plugins.jooq.gradle) alias(libs.plugins.jte.gradle) } version = "0.1" group = "io.wangler" repositories { mavenCentral() } dependencies { annotationProcessor(mn.micronaut.data.processor) annotationProcessor(mn.micronaut.http.validation) annotationProcessor(mn.micronaut.serde.processor) implementation(mn.micronaut.data.jdbc) implementation(mn.micronaut.flyway) implementation(mn.micronaut.serde.jackson) implementation(mn.micronaut.jdbc.hikari) implementation(mn.micronaut.jooq) implementation(mn.micronaut.views.jte) compileOnly(mn.micronaut.http.client) runtimeOnly(mn.logback.classic) runtimeOnly(mn.postgresql) jooqCodegen(mn.postgresql) testImplementation(mn.micronaut.http.client) } application { mainClass.set("io.wangler.Application") } java { sourceCompatibility = JavaVersion.toVersion("21") targetCompatibility = JavaVersion.toVersion("21") } graalvmNative.toolchainDetection.set(false) micronaut { runtime("netty") testRuntime("junit5") processing { incremental(true) annotations("io.wangler.*") } } jte { sourceDirectory.set(file("src/main/jte").toPath()) generate() } // Gradle requires that generateJte is run before some tasks tasks.configureEach { if (name == "inspectRuntimeClasspath") { mustRunAfter("generateJte") } } jooq { configuration { jdbc { url = "jdbc:postgresql:solaria" user = "user" password = "password" driver = "org.postgresql.Driver" } generator { database { name = "org.jooq.meta.postgres.PostgresDatabase" includes = ".*" excludes = "flyway_schema_history" inputSchema = "public" } target { packageName = "io.wangler.solaria" } } } }
我通过在gradle/mn-override.versions.toml中覆盖micronaut-sql版本为5.4.1,以适配JOOQ 3.19.3:
[versions] micronaut-sql = "5.4.1" # to use JOOQ 3.19.3
依赖树显示已正确引入JOOQ 3.19.3:
+--- io.micronaut.sql:micronaut-jooq:5.4.1 | +--- io.micronaut:micronaut-inject:4.2.3 (*) | +--- jakarta.persistence:jakarta.persistence-api:3.1.0 | +--- io.micronaut.sql:micronaut-jdbc:5.4.1 (*) | \--- org.jooq:jooq:3.19.3 | \--- io.r2dbc:r2dbc-spi:1.0.0.RELEASE | \--- org.reactivestreams:reactive-streams:1.0.3 -> 1.0.4
将DDL导入Postgres数据库后,执行./gradlew jooqCodegen可成功在build/generated-sources/jooq生成代码,且IDEA已将该目录识别为额外源文件夹。但当我编写使用生成的JOOQ代码的类:
package io.wangler.solaria.repository; import io.wangler.solaria.Tables; import jakarta.inject.Singleton; import org.jooq.DSLContext; import java.util.List; @Singleton public class DeviceRepository { private final DSLContext dsl; public DeviceRepository(DSLContext dsl) { this.dsl = dsl; } public List<Device> findAll() { return this.dsl.select(Tables.DEVICE.ID, Tables.DEVICE.NAME, Tables.DEVICE.KEY) .from(Tables.DEVICE) .fetchInto(Device.class); } }
执行./gradlew compileJava时出现编译错误:
./src/main/java/io/wangler/solaria/repository/DeviceRepository.java:3: error: cannot find symbol import io.wangler.solaria.Tables; ^ symbol: class Tables location: package io.wangler.solaria
编译器无法找到生成的源文件,请问如何解决该问题?为何IDEA能识别这些生成代码但Gradle构建时无效?
解决方案
核心原因
IDEA会自动扫描build/generated-sources目录并标记为源文件夹,但Gradle默认不会自动将JOOQ生成代码目录加入编译源路径,也未建立compileJava与jooqCodegen任务的依赖关系,导致编译时找不到生成的类。
具体修复步骤
- 将JOOQ生成目录加入Gradle源码集
在build.gradle.kts的java块中添加配置,把JOOQ生成代码目录纳入主源码集:
java { sourceCompatibility = JavaVersion.toVersion("21") targetCompatibility = JavaVersion.toVersion("21") sourceSets["main"].java.srcDir("build/generated-sources/jooq") }
- 建立任务依赖
确保compileJava任务在jooqCodegen执行完成后再运行,添加以下配置:
tasks.compileJava { dependsOn(tasks.jooqCodegen) }
- (可选)优化增量构建
为让Gradle正确检测JOOQ生成代码的变化,可显式配置jooqCodegen任务的输出目录:
tasks.jooqCodegen { outputs.dir("build/generated-sources/jooq") }
验证修复
执行./gradlew clean compileJava,此时Gradle会先运行jooqCodegen生成代码,再编译主源码,编译错误即可消除。
内容的提问来源于stack exchange,提问作者saw303
相关产品推荐
相关产品推荐

