javagradleliquibasejooqjooq-codegen

Runnin generateJooq task with Liquibase of gradle-jooq-plugin returns java.lang.NoClassDefFoundError: liquibase/resource/FileSystemResourceAccessor


I have Java Spring Boot Gradle-Kotlin project in which I am using H2 (DBMS) Jooq and Liquibase. I am trying to run "generateJooq" to generate database schema from Liquibase file, but I am unable to, because I receive this error below:

SLF4J: No SLF4J providers were found.
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See https://www.slf4j.org/codes.html#noProviders for further details.
SLF4J: Class path contains SLF4J bindings targeting slf4j-api versions 1.7.x or earlier.
SLF4J: Ignoring binding found at [jar:file:/C:/Users/Mykolas/.gradle/caches/modules-2/files-2.1/org.slf4j/slf4j-jdk14/1.7.30/d35953dd2fe54ebe39fdf18cfd82fe6eb35b25ed/slf4j-jdk14-1.7.30.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: See https://www.slf4j.org/codes.html#ignoredBindings for an explanation.
Exception in thread "main" java.lang.NoClassDefFoundError: liquibase/resource/FileSystemResourceAccessor
        at org.jooq.meta.extensions.liquibase.LiquibaseDatabase.export(LiquibaseDatabase.java:149)
        at org.jooq.meta.extensions.AbstractInterpretingDatabase.connection(AbstractInterpretingDatabase.java:100)
        at org.jooq.meta.extensions.AbstractInterpretingDatabase.create0(AbstractInterpretingDatabase.java:77)
        at org.jooq.meta.AbstractDatabase.create(AbstractDatabase.java:342)
        at org.jooq.meta.AbstractDatabase.create(AbstractDatabase.java:332)
        at org.jooq.meta.AbstractDatabase.setConnection(AbstractDatabase.java:322)
        at org.jooq.codegen.GenerationTool.run0(GenerationTool.java:546)
        at org.jooq.codegen.GenerationTool.run(GenerationTool.java:239)
        at org.jooq.codegen.GenerationTool.generate(GenerationTool.java:234)
        at org.jooq.codegen.GenerationTool.main(GenerationTool.java:206)
Caused by: java.lang.ClassNotFoundException: liquibase.resource.FileSystemResourceAccessor
        at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641)
        at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188)
        at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:520)
        ... 10 more

> Task :generateJooq FAILED

FAILURE: Build failed with an exception.

My build.gradle.kts file is provided below:

plugins {
    java
    id("org.springframework.boot") version "3.0.2"
    id("io.spring.dependency-management") version "1.1.0"
    id("nu.studer.jooq") version "8.0"
}

buildscript {
    configurations["classpath"].resolutionStrategy.eachDependency {
        if (requested.group == "org.jooq") {
            useVersion("3.16.3")
        }
    }

    dependencies {
        classpath("org.yaml:snakeyaml:1.28")
        classpath("org.jooq:jooq-meta-extensions-liquibase")
        classpath("org.liquibase:liquibase-core")
        classpath("org.slf4j:slf4j-jdk14:1.7.30")
    }


}

group = "com.example"
version = "0.0.1-SNAPSHOT"
java.sourceCompatibility = JavaVersion.VERSION_17

repositories {
    mavenCentral()
}

dependencies {
    implementation("org.springframework.boot:spring-boot-starter-jooq")
    implementation("org.springframework.boot:spring-boot-starter-web")
    implementation("org.liquibase:liquibase-core")
    runtimeOnly("com.h2database:h2")
    testImplementation("org.springframework.boot:spring-boot-starter-test")

    implementation("org.yaml:snakeyaml:1.28")
    implementation("org.jooq:jooq-meta-extensions-liquibase")
    implementation("org.slf4j:slf4j-jdk14:1.7.30")

    jooqGenerator("org.yaml:snakeyaml:1.28")
    jooqGenerator("org.jooq:jooq-meta-extensions-liquibase")
    jooqGenerator("org.liquibase:liquibase-core")
    jooqGenerator("org.slf4j:slf4j-jdk14:1.7.30")
}

tasks.withType<Test> {
    useJUnitPlatform()
}


jooq {
    version.set("3.16.3")

    configurations {
        create("main") {
            generateSchemaSourceOnCompilation.set(true)

            jooqConfiguration.apply {
                logging = org.jooq.meta.jaxb.Logging.WARN

                generator.apply {
                    name = "org.jooq.codegen.KotlinGenerator"

                    target.apply {
                        packageName = "com.example.main.db"
                    }

                    database.apply {
                        name = "org.jooq.meta.extensions.liquibase.LiquibaseDatabase"
                        properties.add(
                                org.jooq.meta.jaxb.Property().withKey("scripts")
                                        .withValue("classpath:src/main/resources/db/changelog/migrations/db.changelog-V1.yaml")
                        )

                        properties.add(
                                org.jooq.meta.jaxb.Property().withKey("includeLiquibaseTables").withValue("false")
                        )

                    }
                }
            }
        }
    }
}

I have configured this file according to the instructions I found on the internet, but it still seems to not be working. I have tried googling solution, but that did not help. I would be thankful if someone could help me out.


Solution

  • Liquibase has incompatibly changed their API: https://github.com/liquibase/liquibase/issues/3478

    This has an impact on third parties that use Liquibase, including jOOQ's LiquibaseDatabase. The relevant issue where this is addressed in jOOQ is: https://github.com/jOOQ/jOOQ/issues/14267

    The above fix will be published only in jOOQ 3.18, soon (probably in Q1 2023). For the time being, make sure you're using the Liquibase version that jOOQ's jooq-meta-extensions-liquibase module depends on, at least for the code generation purpose. It's probably being upgraded by Spring Boot, implicitly, and you didn't specify any explicit version:

    jooqGenerator("org.liquibase:liquibase-core")