Search code examples
gradlejooqmicronaut

Using the official JOOQ Gradle plugin with Micronaut 4 application fails to compile


I'm new to JOOQ and trying to use the recently released and brand new official Gradle plugin of JOOQ with my Micronaut 4 application.

Here is my 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"
            }
        }
    }
}

You probably notices that I'm using the Micronaut's version catalogue to be able to use JOOQ 3.19.3. I overwrite the Micronaut SQL version to 5.4.1 in the gradle/mn-override.versions.toml to be able to consume JOOQ 3.19.3 which is compatible with the new JOOQ Gradle plugin.

[versions]
micronaut-sql = "5.4.1" # to use 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

When I populate my DDL to my Postgres database and then run ./gradlew jooqCodegen, JOOQ's code generator generates all the Java code as expected at build/generated-sources/jooq and the generated folder is added to the IntelliJ project as an additional source folder.

Additional source folder in IDEA

When I then add some code that wants to use the generated JOOQ artifacts

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);
    }
}

and try to compile the project using ./gradlew compileJava I get the error

./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

the compiler does not have the generated sources on its classpath. Does anyone know how to workaround this problem? Why are the generated sources handed over to IDEA, but have no affect in the Gradle build? Any help is much appreciated.


Solution

  • You'll have to add this task dependency to your build.gradle.kts file:

    tasks.named("compileJava") {
        dependsOn(tasks.named("jooqCodegen"))
    }
    

    See discussion here: https://github.com/jOOQ/jOOQ/issues/15966