Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

java.lang.ClassNotFoundException: jakarta.xml.bind.annotation.XmlSchema #209

Closed
LinkedList opened this issue Feb 4, 2022 · 15 comments
Closed

Comments

@LinkedList
Copy link

Hi 👋
Since the upgrade to v 7.0 the generator needs explicit dependency to jakarta.xml.bind:jakarta.xml.bind-api,
I don't know if this is intentional but I couldn't find anything in the README.

Exception in thread "main" java.lang.NoClassDefFoundError: jakarta/xml/bind/annotation/XmlSchema
	at org.jooq.util.jaxb.tools.MiniJAXB.getNamespace(MiniJAXB.java:400)
	at org.jooq.util.jaxb.tools.MiniJAXB.addDefaultNamespace(MiniJAXB.java:188)
	at org.jooq.util.jaxb.tools.MiniJAXB.unmarshal0(MiniJAXB.java:175)
	at org.jooq.util.jaxb.tools.MiniJAXB.unmarshal(MiniJAXB.java:161)
	at org.jooq.codegen.GenerationTool.load(GenerationTool.java:1180)
	at org.jooq.codegen.GenerationTool.main(GenerationTool.java:203)
Caused by: java.lang.ClassNotFoundException: jakarta.xml.bind.annotation.XmlSchema
	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)
	... 6 more
Caused by: java.lang.ClassNotFoundException: jakarta.xml.bind.annotation.XmlSchema

the fix is just adding the dependency: jooqGenerator("jakarta.xml.bind:jakarta.xml.bind-api:3.0.1")

@etiennestuder
Copy link
Owner

etiennestuder commented Feb 4, 2022

Hm, I cannot reproduce it. It should be pulled in as a transitive dependency. All integration tests and examples are working fine. I'll try to investigate. Thanks for reporting.

Do you observe the same thing when running the examples, for exmaple, this one?
https://github.com/etiennestuder/gradle-jooq-plugin/tree/master/example/use_groovy_dsl

@LinkedList
Copy link
Author

@etiennestuder It does work in the example project 🤔 I will investigate why it's happening with our current setup..

@etiennestuder
Copy link
Owner

etiennestuder commented Feb 4, 2022

@LinkedList What version of Gradle and jOOQ are you using in your real project?

@LinkedList
Copy link
Author

@etiennestuder
We have Gradle 7.2, jooq is set to 3.16.3 but I am onto something. Gradle is somehow downgrading the bind-api dependency to 2.3.3

 $ gradle -q dependencyInsight --configuration jooqGenerator --dependency jakarta.xml.bind-api                                                                                                                                                                                                                                                                                                                                                                          
executing gradlew instead of gradle
jakarta.xml.bind:jakarta.xml.bind-api:2.3.3 (selected by rule)
   variant "runtime" [
      org.gradle.status          = release (not requested)
      org.gradle.usage           = java-runtime (not requested)
      org.gradle.libraryelements = jar (not requested)
      org.gradle.category        = library (not requested)
   ]

jakarta.xml.bind:jakarta.xml.bind-api:3.0.0 -> 2.3.3
\--- org.jooq:jooq:3.16.3
     +--- org.jooq:jooq-codegen:3.16.3
     |    \--- jooqGenerator (requested org.jooq:jooq-codegen)
     \--- org.jooq:jooq-meta:3.16.3
          \--- org.jooq:jooq-codegen:3.16.3 (*)

(*) - dependencies omitted (listed previously)

@etiennestuder
Copy link
Owner

Hm, this is not what I'm seeing on my projects nor the example projects.

I see:

$ gr -q dependencyInsight --configuration jooqGenerator --dependency jakarta.xml.bind-api 
jakarta.xml.bind:jakarta.xml.bind-api:3.0.0
   variant "runtime" [
      org.gradle.status          = release (not requested)
      org.gradle.usage           = java-runtime (not requested)
      org.gradle.libraryelements = jar (not requested)
      org.gradle.category        = library (not requested)
   ]

jakarta.xml.bind:jakarta.xml.bind-api:3.0.0
\--- org.jooq:jooq:3.16.3
     +--- org.jooq:jooq-codegen:3.16.3
     |    \--- jooqGenerator (requested org.jooq:jooq-codegen)
     \--- org.jooq:jooq-meta:3.16.3
          \--- org.jooq:jooq-codegen:3.16.3 (*)

(*) - dependencies omitted (listed previously)

Do have some dependency rules specifiec?

Running your command above with --scan might help since you can check the build scan on scans.gradle.com for possibly more dependency insights.

@etiennestuder
Copy link
Owner

Your dependency rule likely comes in via a configurations.all invocation. Maybe you use the Spring dependency mgmt plugin, or the Nebula plugin, or something like this that brings in dependency rules that enforce certain versions. Or maybe you have such rules in your own build.

Note that there is also such a rule in the gradle-jooq-plugin, but it only applies to the jOOQ libraries:
https://github.com/alextu/gradle-jooq-plugin/blob/master/src/main/groovy/nu/studer/gradle/jooq/JooqPlugin.java#L96

@mbrinkg8tr
Copy link

Not sure if this helps, but my build is experiencing the exact same issue, with the exact same results from dependencyInsight. I'd like to add my build.gradle file to the discussion to see if it sheds any light on the subject.

plugins {
    id 'java'
    id 'jacoco'
    id 'maven-publish'
    id 'org.springframework.boot' version '2.3.1.RELEASE'
    id 'com.github.johnrengelman.shadow' version '5.2.0'
    id 'io.spring.dependency-management' version '1.0.9.RELEASE'
    id 'com.jfrog.artifactory' version '4.16.0'
    id 'nu.studer.jooq' version '7.0'
}

ext {
    assertjVersion = '3.22.0'
    awsSdkVersion = '1.11.812'
    awsLambdaEventsVersion = '2.2.9' //version 3.1.0 does not deserialize S3Event properly
    awsLambdaCoreVersion = '1.2.1'
    geojsonJacksonVersion = '1.14'
    lombokVersion = '1.18.22'
    mapstructVersion = '1.4.2.Final'
    postgresVersion = '42.3.2'
    slf4jVersion = '1.7.32'
    springCloudFunctionVersion = '3.0.6.RELEASE'
    springCloudVersion = '2.2.6.RELEASE'
    testNGVersion = '7.4.0'
    msDbSchemaVersion = '0.10.10'
    jooqVersion = '3.16.3'
}

dependencies {
    implementation("org.mapstruct:mapstruct:${mapstructVersion}")
    annotationProcessor("org.mapstruct:mapstruct-processor:${mapstructVersion}")
    annotationProcessor("org.projectlombok:lombok:${lombokVersion}")
    compileOnly("org.projectlombok:lombok:${lombokVersion}")
    implementation("org.springframework.cloud:spring-cloud-function-context")
    implementation("org.springframework.cloud:spring-cloud-starter-function-web")
    implementation("org.slf4j:slf4j-api:${slf4jVersion}")
    implementation("de.grundid.opendatalab:geojson-jackson:${geojsonJacksonVersion}")


    implementation 'org.liquibase:liquibase-core'
    implementation("org.jooq:jooq:${jooqVersion}")
    implementation("org.jooq:jooq-codegen:${jooqVersion}")

    implementation('org.springframework.boot:spring-boot-starter-jooq')
    implementation('org.springframework.boot:spring-boot-starter-data-rest')
    implementation('org.hibernate:hibernate-core:5.6.5.Final')
    implementation("org.postgresql:postgresql:${postgresVersion}")
    jooqGenerator("org.postgresql:postgresql:${postgresVersion}")

    implementation("com.amazonaws:aws-lambda-java-events:${awsLambdaEventsVersion}")
    implementation("com.amazonaws:aws-lambda-java-core:${awsLambdaCoreVersion}")
    implementation("com.amazonaws:aws-java-sdk-s3:${awsSdkVersion}")

    testImplementation('org.springframework.boot:spring-boot-starter-test') {
        exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
    }
    testImplementation("org.testng:testng:${testNGVersion}")
    testImplementation("org.assertj:assertj-core:${assertjVersion}")
}

dependencyManagement {
    imports {
        mavenBom "org.springframework.cloud:spring-cloud-function-dependencies:${springCloudFunctionVersion}"
    }
}


repositories {
    maven {
        url "https://myrepo"
        credentials {
            username "user"
            password "pass"
        }
    }
    mavenCentral()
}

import org.jooq.meta.jaxb.Logging

jooq {
    version = '3.16.3'
    edition = nu.studer.gradle.jooq.JooqEdition.OSS

    configurations {
        main {
            generateSchemaSourceOnCompilation = true
            generationTool {
                logging = Logging.DEBUG
                jdbc {
                    driver = 'org.postgresql.Driver'
                    url = 'jdbc:postgresql://localhost:5432/database'
                    user = 'database'
                    password = 'database'
                }
                generator {
                    name = 'org.jooq.codegen.DefaultGenerator'
                    database {
                        name = 'org.jooq.meta.postgres.PostgresDatabase'
                        inputSchema = 'public'
                        includes = '''
                                        omitted
                        '''
                        forcedTypes {
                            forcedType {
                                name = 'varchar'
                                includeExpression = '.*'
                                includeTypes = 'JSONB?'
                            }
                            forcedType {
                                name = 'varchar'
                                includeExpression = '.*'
                                includeTypes = 'INET'
                            }
                        }
                    }
                    generate {
                        deprecated = true
                        records = true
                        immutablePojos = true
                        fluentSetters = true
                    }
                    target {
                        packageName = 'com.projectname.db'
                        directory = 'build/generated-src/jooq/main'  // default (can be omitted)
                    }
                    strategy.name = 'org.jooq.codegen.DefaultGeneratorStrategy'
                }
            }
        }

    }
}

tasks.generateJooq.with {
//    def out = new ByteArrayOutputStream()
    javaExecSpec = { JavaExecSpec s ->
//        s.standardOutput = out
//        s.errorOutput = out
        s.ignoreExitValue = true
        s.jvmArgs '-Xmx512M'
    }
    execResultHandler = {
        ExecResult r ->
            if (r.exitValue != 0) {
                throw new RuntimeException('jOOQ source code generation failed:\n\n')
            }
    }
}

@mbrinkg8tr
Copy link

mbrinkg8tr commented Feb 4, 2022

Your dependency rule likely comes in via a configurations.all invocation. Maybe you use the Spring dependency mgmt plugin, or the Nebula plugin, or something like this that brings in dependency rules that enforce certain versions. Or maybe you have such rules in your own build.

Note that there is also such a rule in the gradle-jooq-plugin, but it only applies to the jOOQ libraries: https://github.com/alextu/gradle-jooq-plugin/blob/master/src/main/groovy/nu/studer/gradle/jooq/JooqPlugin.java#L96

@etiennestuder That seems correct, when I removed spring dependency management, the code generator started working (although my build broke). Upgrading to the latest (1.0.11.RELEASE) still produces the same issue.

As a workaround, I just put the plugin into isolation:

plugins {
    id 'java'
    id 'jacoco'
    id 'maven-publish'
    id 'org.springframework.boot' version '2.3.1.RELEASE'
    id 'com.github.johnrengelman.shadow' version '5.2.0'
    id 'io.spring.dependency-management' version '1.0.11.RELEASE' apply false
    id 'com.jfrog.artifactory' version '4.16.0'
    id 'nu.studer.jooq' version '7.0'
}

build {

    apply plugin: 'io.spring.dependency-management'

    dependencyManagement {
        imports {
            mavenBom "org.springframework.cloud:spring-cloud-function-dependencies:${springCloudFunctionVersion}"
        }
    }

}

$ ./gradlew -q dependencyInsight --configuration jooqGenerator --dependency jakarta.xml.bind-api 
jakarta.xml.bind:jakarta.xml.bind-api:3.0.0
   variant "runtime" [
      org.gradle.status          = release (not requested)
      org.gradle.usage           = java-runtime (not requested)
      org.gradle.libraryelements = jar (not requested)
      org.gradle.category        = library (not requested)
   ]

jakarta.xml.bind:jakarta.xml.bind-api:3.0.0
\--- org.jooq:jooq:3.16.3
     +--- org.jooq:jooq-codegen:3.16.3
     |    \--- jooqGenerator (requested org.jooq:jooq-codegen)
     \--- org.jooq:jooq-meta:3.16.3
          \--- org.jooq:jooq-codegen:3.16.3 (*)

(*) - dependencies omitted (listed previously)

@etiennestuder
Copy link
Owner

Yep, as suspected. Thanks for the report, @LinkedList and the additional confirmation @mbrinkg8tr.

I'll close this issue now. The gradle-jooq-plugin is applying normal dependency declarations and it is outside of this plugin control what version rules other plugins enforce.

@etiennestuder
Copy link
Owner

I've added a section to the README should this come up again for someone.

@LinkedList
Copy link
Author

Thank you @etiennestuder and @mbrinkg8tr for help analysing this 👍

@hantsy
Copy link

hantsy commented Mar 2, 2022

I've added a section to the README should this come up again for someone.

Any workaround for this?

@hantsy
Copy link

hantsy commented Mar 2, 2022

 .\gradlew -q dependencyInsight --configuration jooqGenerator --dependency jakarta.xml.bind-api 
jakarta.xml.bind:jakarta.xml.bind-api:2.3.3 (selected by rule)
   variant "runtime" [
      org.gradle.status          = release (not requested)
      org.gradle.usage           = java-runtime (not requested)
      org.gradle.libraryelements = jar (not requested)
      org.gradle.category        = library (not requested)
   ]

jakarta.xml.bind:jakarta.xml.bind-api:3.0.0 -> 2.3.3
\--- org.jooq:jooq:3.16.4
     +--- org.jooq:jooq-codegen:3.16.4
     |    \--- jooqGenerator (requested org.jooq:jooq-codegen)
     \--- org.jooq:jooq-meta:3.16.4
          \--- org.jooq:jooq-codegen:3.16.4 (*)

(*) - dependencies omitted (listed previously)

@LinkedList
Copy link
Author

@hantsy explicitly adding the version should work

the fix is just adding the dependency: jooqGenerator("jakarta.xml.bind:jakarta.xml.bind-api:3.0.1")

@hantsy
Copy link

hantsy commented Mar 2, 2022

@LinkedList Thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants