Skip to content

Commit

Permalink
Merged in use-jooq-version-from-compile-classpath (pull request #15)
Browse files Browse the repository at this point in the history
FCSAR-2847 Use jooq version from compile classpath for generation

* FCSAR-2847 Use jooq version from compile classpath for generation


Approved-by: Kamil Gregorczyk
  • Loading branch information
adrianskrobaczrevolut authored and Kamil Gregorczyk committed Dec 28, 2021
1 parent 4d6e005 commit edb64b4
Show file tree
Hide file tree
Showing 6 changed files with 193 additions and 15 deletions.
24 changes: 24 additions & 0 deletions src/main/kotlin/com/revolut/jooq/ChildFirstClassLoader.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import java.net.URL
import java.net.URLClassLoader

class ChildFirstClassLoader(classpath: Array<URL>?, parent: ClassLoader?) : URLClassLoader(classpath, parent) {
private val system: ClassLoader = getSystemClassLoader()

@Synchronized
override fun loadClass(name: String, resolve: Boolean): Class<*>? {
var c = findLoadedClass(name)
if (c == null) {
c = try {
findClass(name)
} catch (e: ClassNotFoundException) {
try {
super.loadClass(name, resolve)
} catch (e2: ClassNotFoundException) {
system.loadClass(name)
}
}
}
if (resolve) resolveClass(c)
return c
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ class FlywaySchemaVersionProvider : SchemaVersionProvider {
private val defaultSchemaName = ThreadLocal<String>()
private val flywayTableName = ThreadLocal<String>()

@JvmStatic
fun setup(defaultSchemaName: String, flywayTableName: String) {
this.defaultSchemaName.set(defaultSchemaName)
this.flywayTableName.set(flywayTableName)
Expand Down
54 changes: 43 additions & 11 deletions src/main/kotlin/com/revolut/jooq/GenerateJooqClassesTask.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.revolut.jooq

import ChildFirstClassLoader
import groovy.lang.Closure
import org.flywaydb.core.Flyway
import org.flywaydb.core.api.Location.FILESYSTEM_PREFIX
Expand All @@ -11,13 +12,12 @@ import org.gradle.api.plugins.JavaPlugin
import org.gradle.api.plugins.JavaPluginConvention
import org.gradle.api.tasks.*
import org.gradle.api.tasks.SourceSet.MAIN_SOURCE_SET_NAME
import org.jooq.codegen.GenerationTool
import org.jooq.codegen.JavaGenerator
import org.jooq.meta.jaxb.*
import org.jooq.meta.jaxb.Target
import java.io.File
import java.io.IOException
import java.net.URL
import java.net.URLClassLoader
import javax.xml.bind.JAXBContext

@CacheableTask
open class GenerateJooqClassesTask : DefaultTask() {
Expand Down Expand Up @@ -175,27 +175,56 @@ open class GenerateJooqClassesTask : DefaultTask() {

private fun generateJooqClasses(jdbcAwareClassLoader: ClassLoader, dbHost: String) {
project.delete(outputDirectory)
val config = prepareConfig(dbHost)
val configFile = writeConfigToTemporaryFile(config)
generateJooqClassesUsingClassloader(jdbcAwareClassLoader, configFile)
}

private fun prepareConfig(dbHost: String): Configuration {
val db = getDb()
val jdbc = getJdbc()
FlywaySchemaVersionProvider.setup(defaultFlywaySchema(), flywayTableName())
SchemaPackageRenameGeneratorStrategy.schemaToPackageMapping.set(schemaToPackageMapping.toMap())
val generator = generatorConfig.get()
excludeFlywaySchemaIfNeeded(generator)
val tool = GenerationTool()
tool.setClassLoader(jdbcAwareClassLoader)
tool.run(Configuration()
return Configuration()
.withLogging(Logging.DEBUG)
.withJdbc(Jdbc()
.withDriver(jdbc.driverClassName)
.withUrl(db.getUrl(dbHost))
.withUser(db.username)
.withPassword(db.password))
.withGenerator(generator))
.withGenerator(generator)
}

private fun writeConfigToTemporaryFile(config: Configuration): File {
val configFile = File(temporaryDir, "config.xml")
configFile.writer().use {
JAXBContext.newInstance(config.javaClass)
.createMarshaller()
.marshal(config, it)
}
if (logger.isDebugEnabled) {
logger.debug("config for generator: {}", configFile.readText())
}
return configFile
}

private fun generateJooqClassesUsingClassloader(jdbcAwareClassLoader: ClassLoader, configFile: File) {
jdbcAwareClassLoader.run {
loadClass(FlywaySchemaVersionProvider::class.qualifiedName)
.getDeclaredMethod("setup", String::class.java, String::class.java)
.invoke(null, defaultFlywaySchema(), flywayTableName())
loadClass(SchemaPackageRenameGeneratorStrategy::class.qualifiedName)
.getDeclaredMethod("setup", Map::class.java)
.invoke(null, schemaToPackageMapping.toMap())
loadClass("org.jooq.codegen.GenerationTool")
.getDeclaredMethod("main", Array<String>::class.java)
.invoke(null, arrayOf(configFile.absolutePath))
}
}

private fun prepareGeneratorConfig(): Generator {
return Generator()
.withName(JavaGenerator::class.qualifiedName)
.withName("org.jooq.codegen.JavaGenerator")
.withStrategy(Strategy()
.withName(SchemaPackageRenameGeneratorStrategy::class.qualifiedName))
.withDatabase(Database()
Expand Down Expand Up @@ -229,7 +258,10 @@ open class GenerateJooqClassesTask : DefaultTask() {
}

private fun buildJdbcArtifactsAwareClassLoader(): ClassLoader {
return URLClassLoader(resolveJdbcArtifacts(), project.buildscript.classLoader)
return ChildFirstClassLoader(
resolveJdbcArtifacts()
+ arrayOf(SchemaPackageRenameGeneratorStrategy.javaClass.protectionDomain.codeSource.location),
project.buildscript.classLoader)
}

@Throws(IOException::class)
Expand Down
20 changes: 19 additions & 1 deletion src/main/kotlin/com/revolut/jooq/JooqDockerPlugin.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,32 @@ package com.revolut.jooq

import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.api.artifacts.Configuration

open class JooqDockerPlugin : Plugin<Project> {

override fun apply(project: Project) {
project.extensions.create("jooq", JooqExtension::class.java, project.name)
project.configurations.create("jdbc")
val configuration = project.configurations.create("jdbc")
addJooqCodegenDependencyToPluginRuntime(project, configuration)
project.tasks.create("generateJooqClasses", GenerateJooqClassesTask::class.java) {
group = "jooq"
}
}

private fun addJooqCodegenDependencyToPluginRuntime(project: Project, configuration: Configuration) {
project.dependencies.add(configuration.name, project.provider {
findJooqVersionOnCompileClasspath(project)
?.let { "org.jooq:jooq-codegen:$it" }
?: throw IllegalStateException("Unable to resolve jooq version. Please add jooq to your classpath")
})
}

private fun findJooqVersionOnCompileClasspath(project: Project) =
project.configurations.getByName("compileClasspath")
.resolvedConfiguration
.resolvedArtifacts
.map { it.moduleVersion.id }
.find { it.name == "jooq" }
?.version
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,12 @@ import org.jooq.meta.SchemaDefinition

class SchemaPackageRenameGeneratorStrategy : DefaultGeneratorStrategy() {
companion object {
val schemaToPackageMapping: ThreadLocal<Map<String, String>> = ThreadLocal.withInitial { emptyMap() }
private val schemaToPackageMapping: ThreadLocal<Map<String, String>> = ThreadLocal.withInitial { emptyMap() }

@JvmStatic
fun setup(mapping: Map<String, String>) {
schemaToPackageMapping.set(mapping)
}
}

override fun getJavaIdentifier(definition: Definition?): String {
Expand Down
Loading

0 comments on commit edb64b4

Please sign in to comment.