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

Gradle配置Jooq自定义生成器遇类找不到问题求助

解决Jooq自定义生成器ClassNotFoundException问题

问题描述

尝试将Jooq代码生成切换为自定义生成器my.custom.GeneratorKt时,执行Gradle任务抛出类找不到异常:

Caused by: java.lang.ClassNotFoundException: my.custom.GeneratorKt
        at org.gradle.internal.classloader.VisitableURLClassLoader$InstrumentingVisitableURLClassLoader.findClass(VisitableURLClassLoader.java:186)
        at org.jooq.meta.ClassUtils.loadClass(ClassUtils.java:55)
        at org.jooq.codegen.GenerationTool.loadClass(GenerationTool.java:1224)
        at org.jooq.codegen.GenerationTool.run0(GenerationTool.java:399)
        at org.jooq.codegen.GenerationTool.run(GenerationTool.java:246)
        at org.jooq.codegen.GenerationTool.generate(GenerationTool.java:241)
        ...

当前Gradle任务代码如下:

val jooqGenerateTask = task("jooqGenerate") {
    doLast {
        val initDir = rootProject.projectDir.absolutePath + "/docker/postgres/"
        val container = KPostgreSQLContainer("postgres:13.12")
            .withDatabaseName("jooq")
            .withFileSystemBind(initDir, "/docker-entrypoint-initdb.d")
            .withTmpFs(
                mapOf(
                    "/var/lib/postgresql/data" to "rw"
                )
            )
        container.start()

        val config = Configuration()
            .withJdbc(
                Jdbc()
                    .withDriver("org.postgresql.Driver")
                    .withUrl(container.jdbcUrl)
                    .withUser(container.username)
                    .withPassword(container.password)
            )
            .withGenerator(
                Generator()
                    // Cannot find this class
                    .withName("my.custom.GeneratorKt")
                    .withDatabase(
                        Database()
                            .withName("org.jooq.meta.postgres.PostgresDatabase")
                            .withIncludes(".*")
                            .withExcludes("schema_version")
                            .withInputSchema("public")
                            .withIncludeTables(true)
                            .withIncludeRoutines(false)
                            .withIncludePackages(false)
                            .withIncludeUDTs(false)
                            .withIncludeSequences(false)
                            .withForcedTypes(
                                ForcedType()
                                    .withUserType(JsonObject::class.java.name)
                                    .withConverter(JSONBToJsonObjectConverter::class.java.name)
                                    .withIncludeTypes("jsonb")
                            )
                    )
                    .withGenerate(
                        Generate()
                            .withDeprecated(false)
                            .withRecords(true)
                            .withInterfaces(false)
                            .withFluentSetters(true)
                            .withPojos(false)
                            .withDaos(true)
                    )
                    .withTarget(
                        JooqTarget()
                            .withPackageName("my.jooq")
                            .withDirectory("$projectDir/src/main/java")
                    )
                    .withStrategy(
                        Strategy()
                            .withName("io.github.jklingsporn.vertx.jooq.generate.VertxGeneratorStrategy")
                    )
            )
        GenerationTool.generate(config)
        container.stop()
    }
}

原因分析

Gradle任务的默认类加载器不包含项目自身的编译产物,自定义生成器类属于项目代码,因此Jooq的GenerationTool无法在任务执行时加载到该类。

解决方案

需要为jooqGenerate任务配置正确的类路径,使其包含项目编译输出和依赖库,同时确保自定义生成器类在任务执行前已编译完成。

1. 修改任务配置,添加类路径依赖

将任务类型指定为JavaExec(或直接配置类路径),并添加项目主源码的编译输出和编译依赖到任务类路径:

val jooqGenerateTask = task("jooqGenerate", JavaExec::class) {
    // 配置任务类路径,包含项目编译输出和所有编译依赖
    classpath = sourceSets.main.get().output + sourceSets.main.get().compileClasspath

    doLast {
        // 原有容器启动、Jooq配置、代码生成逻辑保持不变
        val initDir = rootProject.projectDir.absolutePath + "/docker/postgres/"
        val container = KPostgreSQLContainer("postgres:13.12")
            .withDatabaseName("jooq")
            .withFileSystemBind(initDir, "/docker-entrypoint-initdb.d")
            .withTmpFs(
                mapOf(
                    "/var/lib/postgresql/data" to "rw"
                )
            )
        container.start()

        val config = Configuration()
            .withJdbc(
                Jdbc()
                    .withDriver("org.postgresql.Driver")
                    .withUrl(container.jdbcUrl)
                    .withUser(container.username)
                    .withPassword(container.password)
            )
            .withGenerator(
                Generator()
                    .withName("my.custom.GeneratorKt")
                    .withDatabase(
                        Database()
                            .withName("org.jooq.meta.postgres.PostgresDatabase")
                            .withIncludes(".*")
                            .withExcludes("schema_version")
                            .withInputSchema("public")
                            .withIncludeTables(true)
                            .withIncludeRoutines(false)
                            .withIncludePackages(false)
                            .withIncludeUDTs(false)
                            .withIncludeSequences(false)
                            .withForcedTypes(
                                ForcedType()
                                    .withUserType(JsonObject::class.java.name)
                                    .withConverter(JSONBToJsonObjectConverter::class.java.name)
                                    .withIncludeTypes("jsonb")
                            )
                    )
                    .withGenerate(
                        Generate()
                            .withDeprecated(false)
                            .withRecords(true)
                            .withInterfaces(false)
                            .withFluentSetters(true)
                            .withPojos(false)
                            .withDaos(true)
                    )
                    .withTarget(
                        JooqTarget()
                            .withPackageName("my.jooq")
                            .withDirectory("$projectDir/src/main/java")
                    )
                    .withStrategy(
                        Strategy()
                            .withName("io.github.jklingsporn.vertx.jooq.generate.VertxGeneratorStrategy")
                    )
            )
        GenerationTool.generate(config)
        container.stop()
    }
}

// 确保代码生成任务依赖于编译任务,保证自定义生成器类已编译完成
jooqGenerateTask.dependsOn(tasks.compileJava)

2. 若自定义生成器在单独模块

如果自定义生成器放在单独的Gradle模块(如:jooq-generator),需先在当前模块添加对该模块的依赖:

dependencies {
    implementation(project(":jooq-generator"))
}

然后修改任务类路径,包含该模块的编译输出:

classpath = sourceSets.main.get().output + 
             sourceSets.main.get().compileClasspath + 
             project(":jooq-generator").sourceSets.main.get().output

内容的提问来源于stack exchange,提问作者Chris

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 22:08:13