java.lang.ClassNotFoundException: jakarta.xml.bind.annotation.XmlSchema
LinkedList opened this issue ยท 15 comments
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")
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
@etiennestuder It does work in the example project ๐ค I will investigate why it's happening with our current setup..
@LinkedList What version of Gradle and jOOQ are you using in your real project?
@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)
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.
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
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')
}
}
}
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)
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.
I've added a section to the README should this come up again for someone.
Thank you @etiennestuder and @mbrinkg8tr for help analysing this ๐
I've added a section to the README should this come up again for someone.
Any workaround for this?
.\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)
@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")
@LinkedList Thanks.