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
相关产品推荐
相关产品推荐

