jOOQ代码生成自定义策略类报ClassNotFoundException解决方法
问题背景
尝试为jOOQ自动生成的POJO类添加Pojo后缀,对应的自定义策略实现逻辑如下:
package my.app.jooq.strategy import org.jooq.codegen.DefaultGeneratorStrategy import org.jooq.codegen.GeneratorStrategy import org.jooq.codegen.GeneratorStrategy.Mode.POJO import org.jooq.meta.Definition class MyGeneratorStrategy : DefaultGeneratorStrategy() { override fun getJavaClassName(definition: Definition, mode: GeneratorStrategy.Mode): String { return when (mode) { POJO -> super.getJavaClassName(definition, mode) + "Pojo" else -> super.getJavaClassName(definition, mode) } } }
代码生成流程始终无法识别该类,抛出ClassNotFoundException异常。根据jOOQ官方社区指引,单独拆分独立的策略模块存放该自定义策略类,构建依赖结构满足:代码生成模块依赖策略模块,策略模块依赖jOOQ基础库,但调整后问题依然存在,报错日志如下:
PM org.jooq.tools.JooqLogger error SEVERE: Error in file: /home/user/code/my-app/backend/db/build/tmp/generateMyAppJooq/config.xml. Error : my.app.jooq.strategy.MyGeneratorStrategy java.lang.ClassNotFoundException: my.app.jooq.strategy.MyGeneratorStrategy at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:581) at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178) at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:522) at org.jooq.codegen.GenerationTool.loadClass0(GenerationTool.java:1075) at org.jooq.codegen.GenerationTool.loadClass(GenerationTool.java:1005) at org.jooq.codegen.GenerationTool.run0(GenerationTool.java:405) at org.jooq.codegen.GenerationTool.run(GenerationTool.java:233) at org.jooq.codegen.GenerationTool.generate(GenerationTool.java:228) at org.jooq.codegen.GenerationTool.main(GenerationTool.java:200)
以下是代码生成模块的Gradle配置(基于nu.studer.jooq插件实现):
plugins { id 'nu.studer.jooq' version "${plugin_jooq}" id 'io.spring.dependency-management' } dependencyManagement { imports { mavenBom SpringBootPlugin.BOM_COORDINATES mavenBom "org.jetbrains.kotlin:kotlin-bom:${fw_kotlin}" } } dependencies { api "org.postgresql:postgresql" implementation project(":backend-jooq-config") api "org.springframework.boot:spring-boot-starter-jooq" implementation "org.jooq:jooq-meta" implementation "org.jooq:jooq-codegen" jooqGenerator "org.postgresql:postgresql" } jooq { version = dependencyManagement.importedProperties['jooq.version'] edition = nu.studer.gradle.jooq.JooqEdition.OSS configurations { myApp { generateSchemaSourceOnCompilation = true generationTool { logging = org.jooq.meta.jaxb.Logging.WARN jdbc { driver = 'org.postgresql.Driver' url = 'jdbc:postgresql://localhost:5432/myapp' user = 'user' password = 'password' properties { property { key = 'PAGE_SIZE' value = 2048 } } } generator { name = 'org.jooq.codegen.DefaultGenerator' strategy { name = 'my.app.jooq.strategy.MyGeneratorStrategy' } database { name = 'org.jooq.meta.postgres.PostgresDatabase' inputSchema = 'public' includes = '.*' excludes = '' } generate { daos = true springAnnotations = true } target { directory = 'src/main/java' packageName = 'my.app.db' } } } } } }
已确认自定义策略类已经成功编译,对应class文件已正常生成,编译产物验证结果如下:
find .. -name "*GeneratorStrategy*" ../backend/jooq-config/build/classes/kotlin/main/my/app/jooq/strategy/MyGeneratorStrategy.class ../backend/jooq-config/build/classes/kotlin/main/my/app/jooq/strategy/MyGeneratorStrategy$WhenMappings.class ../backend/jooq-config/src/main/kotlin/my/app/jooq/strategy/MyGeneratorStrategy.kt
根因分析
nu.studer.jooq插件执行代码生成任务时,使用独立的jooqGenerator配置类路径加载运行时代码,不会读取项目主源码的implementation/api依赖。当前配置仅将自定义策略所在模块加入了主源码依赖,代码生成进程的类路径中不存在该策略类,因此抛出ClassNotFoundException。
修复方案
- 调整依赖配置,将自定义策略所在模块从
implementation依赖迁移到jooqGenerator依赖下,保证代码生成进程可以加载到该类。 - 由于自定义策略使用Kotlin编写,需要额外将Kotlin标准库加入
jooqGenerator类路径,避免类加载时缺少Kotlin运行时依赖。
修改后的dependencies块示例:
dependencies { api "org.postgresql:postgresql" // 主代码如果需要引用策略模块的内容保留该行,不需要可删除 implementation project(":backend-jooq-config") api "org.springframework.boot:spring-boot-starter-jooq" implementation "org.jooq:jooq-meta" implementation "org.jooq:jooq-codegen" jooqGenerator "org.postgresql:postgresql" // 将自定义策略模块加入代码生成类路径 jooqGenerator project(":backend-jooq-config") // 加入Kotlin标准库,匹配项目使用的Kotlin版本 jooqGenerator "org.jetbrains.kotlin:kotlin-stdlib:${fw_kotlin}" }
修改完成后,先执行./gradlew :backend-jooq-config:build编译策略模块,再执行jOOQ代码生成任务即可正常加载自定义策略。
内容的提问来源于stack exchange,提问作者User1291
相关产品推荐
相关产品推荐

