A Gradle plugin for working with the jOOQ code generation tool that supports the Gradle Kotlin DSL.
This project started as a Kotlin port of the Groovy-based gradle-jooq-plugin and was initially developed because it was decided that the Groovy plugin would not add Kotlin DSL support.
Tested with jOOQ versions 3.10, 3.11, 3.12 and 3.13 (Open Source and Pro editions) on Java 1.8, 11 and 13, and with Gradle 5+.
The plugin id needs to be added to the plugins
block in the build.gradle.kts
file in order to be used.
plugins {
id("dev.bombinating.jooq-codegen") version "1.7.0"
}
The JDBC driver for introspecting the database must be provided in the dependencies
block using the jooqRuntime
scope, which is created by the plugin. For example:
dependencies {
jooqRuntime(group = "org.postgresql", name = "postgresql", version = "42.2.6")
}
The plugin defines an extension, jooq
, which (optionally) allows both the version and edition of the jOOQ code generation library to be defined, as well as information about the code generation itself.
If the edition
or version
is not specified, they default to OpenSource
and 3.13.0
, respectively.
The code generation properties (logging
, onError
, jdbc
and generator
) come from the jOOQ code generation Configuration
class (from the jOOQ codegen XSD). The plugin provides extension methods to define the properties in a "closure" style.
Finally, the plugin provides two additional properties, runConfig
and resultHandler
, that can be used to configure the JVM the jOOQ code generation process is run in and to provide a handler for termination of the JVM the code generation was run in, respectively.
Property |
Description |
Example |
|
jOOQ edition to use (OpenSource, Pro, ProJava8, ProJava6) |
|
|
jOOQ version to use |
|
|
jOOQ code generation config logging setting |
|
|
jOOQ error configuration |
|
|
jOOQ code generation config jdbc settings` |
jooq { url = ... user = ... password = ... ... } |
|
jOOQ code generation config generator settings` |
generator { database { ... } target { ... } ... } |
|
JVM config for running the jOOQ |
|
|
Result handler for result for running jOOQ |
|
The plugin also defines a task, jooq
, which invokes the jOOQ code generation functionality using the configuration in the jooq
extension block.
$ ./gradlew jooq
There are no dependencies on this task and this task does not have any dependencies on other tasks. Therefore, after running the jooq
task, it is necessary to run the build
task. It is also necessary to add the directory into which the code is being generated into the source set.
To define additional jOOQ code generation configurations, register/create tasks of type JooqTask
.
The JooqTask
has the same six code generation-related properties as the jOOQ extension. The jOOQ edition
and version
properties are not available in the task.
Property |
Description |
Example |
|
jOOQ code generation config logging setting |
|
|
jOOQ error configuration |
|
|
jOOQ code generation config jdbc settings` |
jooq { url = ... user = ... password = ... ... } |
|
jOOQ code generation config generator settings` |
generator { database { ... } target { ... } ... } |
|
JVM config for running the jOOQ |
|
|
Result handler for result for running jOOQ |
|
For example:
import dev.bombinating.gradle.jooq.*
...
tasks.register<JooqTask>("jooqAccounting") {
jdbc {
...
}
generator {
...
}
logging = ...
}
This task can be invoked like any other Gradle task:
$ ./gradlew jooqAccounting
The plugin configures SLF4J and Logback as the logging library for the plugin and provides a default logback.xml
file that specifies the log format for the code generation.
To provide a different Logback configuration, add the directory containing the logback.xml
file to the jooqRuntime
configuration. For example:
jooqRuntime(files("..."))
The plugin will pass jOOQ-related codegen properties to the code generation process.
Using the jOOQ extension (which defines a task with the name jooq
), properties that start with jooq.
are passed to the generation tool.
For other jOOQ tasks (i.e, ones that aren’t named jooq
), properties of the form <task name>.jooq.
are passed to the generation tool with the <task name>.
removed (e.g., for a task called accounting
, the property accounting.jooq.codegen.jdbc.url
would be passed to the code generator as jooq.codegen.jdbc.url
).
The Spring Boot Plugin uses the Spring Dependency Management Plugin to manage dependencies. The jOOQ library is one of the dependencies that the Spring Boot plugin manages. If the Spring Dependency Management Plugin is detected, the jOOQ plugin will set the ext["jooq.version"]
value based on the value configured in the jOOQ plugin.
-
In this plugin, the
jooq
extension defines a single jOOQ code generation task calledjooq
. Other jOOQ code generation tasks are explicitly defined using the Gradle task mechanism rather than being implicitly created in thejooq
extension block. For example:
...
tasks.register<JooqTask>("...") {
jdbc {
...
}
generator {
...
}
...
}
...
-
This plugin does not create a task dependency between the jOOQ code generation and the Java compilation task. Instead, if desired, the dependency can be set up explicitly in Gradle.
...
tasks.getByName("compileJava").dependsOn(tasks.getByName("jooq"))
...
The plugin works by generating a jOOQ XML configuration file and then invoking the GenerationTool
class on it.
There are four types of tests for the plugin:
-
testing that the extension methods create the correct
Configuration
object -
testing that the plugin works with the H2 database
-
testing that the plugin works with PostgreSQL
-
testing that the plugin works with SQL Server
For the PostgreSQL and SQL Server databases, the tests use the Test Containers library to run the databases in a Docker container.
By default, the tests requiring Docker are disabled. To enable them, set the JOOQ_CONTAINER_TESTS
environment variable to true
.
By default, only the Open Source version of jOOQ is tested. In order to also test the Pro version, set the JOOQ_PRO_TEST
environment to true
(this will test both the Pro and Pro Java 8 versions). In addition, the JOOQ_REPO_URL
, JOOQ_REPO_USERNAME
and JOOQ_REPO_PASSWORD
environment variables also need to be specified in order for the tests to find the jOOQ Pro artifacts.
In order to run the SQL Server tests (since they require both a Docker container and the Pro version of jOOQ), the JOOQ_CONTAINER_TESTS
and JOOQ_PRO_TEST
environment variables must be set to true
and the JOOQ_REPO_URL
, JOOQ_REPO_USERNAME
and JOOQ_REPO_PASSWORD
must also be specified.
To push to a local Maven repository:
$ ./gradlew clean build publishToMavenLocal
To push a snapshot to Artifactory:
$ ./gradlew clean build artifactoryPublish -PbintrayUser=... -PbintrayKey=...
To create a release and create a tag in git for it:
$ ./gradlew clean build release
To push a release to bintray:
$ ./gradlew clean build bintrayUpload -PbintrayUser=... -PbintrayKey=...
To push a release to the Gradle plugin repository:
$ ./gradlew clean build publishPlugins -Pgradle.publish.key=... -Pgradle.publish.secret=...
In this example, a variable, genDir
, is defined for the directory the code will be generated into, and this directory is added to the "main" sourceSets
and also used in the target
jOOQ configuration.
The database connection info comes from a properties file or from Gradle -P
commandline arguments.
import dev.bombinating.gradle.jooq.*
val genDir = "$projectDir/generated/src/main/java"
val jooqUrl: String by project
val jooqUsername: String by project
val jooqPassword: String by project
plugins {
java
id("dev.bombinating.jooq-codegen") version "1.7.0"
}
sourceSets["main"].java {
srcDir(genDir)
}
repositories {
mavenLocal()
mavenCentral()
}
dependencies {
compile(group = "org.jooq", name = "jooq", version = "3.13.0")
jooqRuntime(group = "org.postgresql", name = "postgresql", version = "42.2.8")
}
jooq {
jdbc {
url = jooqUrl
username = jooqUsername
password = jooqPassword
}
generator {
database {
inputSchema = "public"
}
target {
directory = genDir
packageName = "com.acme.domain.db"
}
}
}
The jOOQ code generation, and subsequent build, can be invoked as:
$ ./gradlew clean jooq build
The first half of this example is the same as above, except:
-
the jOOQ edition is specified (
ProJava8
) -
the jOOQ version is specified (
3.13.0
) -
the JVM config for running the code generation tool is specified (
-Xmx2g
) -
a result handler prints the exit value of the code generation tool
-
the code generation logging is specified (
DEBUG
)
In addition, an explicit jOOQ task called accounting
is defined. This is associated with an Oracle database; like the configuration defined in the jooq
extension, the connection info is specified using the Gradle by project
construction and read from a properties file or from the commandline. The example also shows a more sophisticated jOOQ configuration.
Finally, the Java compilation is set to depend on the jOOQ code generation for both the jooq
and accounting
tasks.
import dev.bombinating.gradle.jooq.*
import org.jooq.meta.jaxb.Logging
val genDir = "$projectDir/generated/src/main/java"
val jooqUrl: String by project
val jooqUsername: String by project
val jooqPassword: String by project
val oracleUrl: String by project
val oracleUsername: String by project
val oraclePassword: String by project
val oracleSchema: String by project
plugins {
java
id("dev.bombinating.jooq-codegen") version "1.7.0"
}
sourceSets["main"].java {
srcDir(genDir)
}
repositories {
mavenLocal()
mavenCentral()
}
dependencies {
compile(group = "org.jooq", name = "jooq", version = "3.13.0")
jooqRuntime(group = "org.postgresql", name = "postgresql", version = "42.2.8")
jooqRuntime(group = "com.oracle.ojdbc", name = "ojdbc8", version = "19.3.0.0")
}
jooq {
edition = JooqEdition.ProJava8
version = "3.13.0"
runConfig { jvmArgs = listOf("-Xmx2g") }
resultHandler { println("The exit value of the code generation was: $exitValue") }
logging = Logging.DEBUG
jdbc {
url = jooqUrl
username = jooqUsername
password = jooqPassword
}
generator {
database {
inputSchema = "public"
}
target {
directory = genDir
packageName = "com.acme.domain.db.pg"
}
}
}
val accounting = tasks.register("accounting") {
jdbc {
driver = "oracle.jdbc.driver.OracleDriver"
url = oracleUrl
username = oracleUsername
password = oraclePassword
schema = oracleSchema
}
generator {
generate {
isJavaTimeTypes = true
}
database {
name = "org.jooq.meta.oracle.OracleDatabase"
includes = ".*"
excludes = "^BIN\\$.*|flyway_schema_history"
inputSchema = oracleSchema
forcedTypes {
forcedType {
name = "BOOLEAN"
expression = ".*_IND"
types = ".*"
}
}
}
target {
directory = genDir
packageName = "com.acme.domain.db.oracle"
}
}
logging = Logging.DEBUG
}
tasks.getByName("compileJava").dependsOn(jooq2, tasks.getByName("jooq"))
To generate the code related to both databases, it is sufficient to simply call the build
task since it has a dependency on both the joo
and accounting
tasks Gradle and will therefore ensure that the the source code has been generated from both databases first.
$ ./gradlew clean build