Coder Social home page Coder Social logo

revolut-engineering / jooq-plugin Goto Github PK

View Code? Open in Web Editor NEW
69.0 6.0 28.0 240 KB

Plugin for generating jOOQ classes using dockerized databases

License: Apache License 2.0

Kotlin 17.80% Groovy 56.53% Java 25.67%
jooq jooq-generator docker database kotlin-dsl gradle gradle-kotlin-dsl gradle-plugin

jooq-plugin's Introduction

Gradle Docker jOOQ Plugin

Build Status codecov Gradle Plugins Release

This repository contains Gradle plugin for generating jOOQ classes in dockerized databases. Plugin registers task generateJooqClasses that does following steps:

  • pulls docker image
  • starts database container
  • runs migrations using Flyway
  • generates jOOQ classes

Use:

  • 0.3.x and later for jOOQ versions 3.12.x and later
  • 0.2.x and later releases for jOOQ versions 3.11.x and later
  • For earlier versions use 0.1.x release

Examples

By default plugin is configured to work with PostgreSQL, so the following minimal config is enough:

plugins {
  id("com.revolut.jooq-docker")
}

repositories {
  mavenCentral()
}

dependencies {
  implementation("org.jooq:jooq:3.14.15")
  jdbc("org.postgresql:postgresql:42.2.5")
}

It will look for migration files in src/main/resources/db/migration and will output generated classes to build/generated-jooq in package org.jooq.generated. All of that details can be configured on the task itself as shown in examples below.

Configuring schema names and other parameters of the task:

plugins {
  id("com.revolut.jooq-docker")
}

repositories {
  mavenCentral()
}

tasks {
  generateJooqClasses {
    schemas = arrayOf("public", "other_schema")
    basePackageName = "org.jooq.generated"
    inputDirectory.setFrom(project.files("src/main/resources/db/migration"))
    outputDirectory.set(project.layout.buildDirectory.dir("generated-jooq"))
    flywayProperties = mapOf("flyway.placeholderReplacement" to "false")
    excludeFlywayTable = true
    outputSchemaToDefault = setOf("public")
    schemaToPackageMapping = mapOf("public" to "fancy_name")
    customizeGenerator {
      /* "this" here is the org.jooq.meta.jaxb.Generator configure it as you please */
    }
  }
}

dependencies {
  implementation("org.jooq:jooq:3.14.15")
  jdbc("org.postgresql:postgresql:42.2.5")
}

To configure the plugin to work with another DB like MySQL following config can be applied:

plugins {
  id("com.revolut.jooq-docker")
}

repositories {
  mavenCentral()
}

jooq {
  image {
      repository = "mysql"
      tag = "8.0.15"
      envVars = mapOf(
          "MYSQL_ROOT_PASSWORD" to "mysql",
          "MYSQL_DATABASE" to "mysql")
      containerName = "uniqueMySqlContainerName"
      readinessProbe = { host: String, port: Int ->
          arrayOf("sh", "-c", "until mysqladmin -h$host -P$port -uroot -pmysql ping; do echo wait; sleep 1; done;")
      }
  }
  
  db {
      username = "root"
      password = "mysql"
      name = "mysql"
      port = 3306
  }
  
  jdbc {
      schema = "jdbc:mysql"
      driverClassName = "com.mysql.cj.jdbc.Driver"
      jooqMetaName = "org.jooq.meta.mysql.MySQLDatabase"
      urlQueryParams = "?useSSL=false"
  }
}

dependencies {
  implementation("org.jooq:jooq:3.14.15")
  jdbc("mysql:mysql-connector-java:8.0.15")
}

To register custom types:

plugins {
  id("com.revolut.jooq-docker")
}

repositories {
  mavenCentral()
}

tasks {
  generateJooqClasses {
    customizeGenerator {
      database.withForcedTypes(
              ForcedType()
                      .withUserType("com.google.gson.JsonElement")
                      .withBinding("com.example.PostgresJSONGsonBinding")
                      .withTypes("JSONB")
      )
    }    
  }
}

dependencies {
  implementation("org.jooq:jooq:3.14.15")
  jdbc("org.postgresql:postgresql:42.2.5")
}

To exclude flyway schema history table from generated classes:

plugins {
  id("com.revolut.jooq-docker")
}

repositories {
  mavenCentral()
}

tasks {
  generateJooqClasses {
    schemas = arrayOf("other")
    customizeGenerator {
      database.withExcludes("flyway_schema_history")
    }
  }
}

dependencies {
  implementation("org.jooq:jooq:3.14.15")
  jdbc("org.postgresql:postgresql:42.2.5")
}

To enforce version of the plugin dependencies:

plugins {
  id("com.revolut.jooq-docker")
}

buildscript {
  repositories {
    mavenCentral()
  }

  dependencies {
    classpath("org.jooq:jooq-codegen:3.12.0") {
      isForce = true
    }
  }
}

repositories {
  mavenCentral()
}

dependencies {
  implementation("org.jooq:jooq:3.12.0")
  jdbc("org.postgresql:postgresql:42.2.5")
}

Remote docker setup

The library plugin uses to communicate with docker daemon will pick up your environment variables like DOCKER_HOST and use them for connection (all config options here). Plugin then, based on this config, will try to figure out the host on which database is exposed, if it fail you can override it the following way:

plugins {
  id("com.revolut.jooq-docker")
}


jooq {
    db {
        hostOverride = "localhost"
    }
}

For the readiness probe plugin will always use localhost 127.0.0.1 as it's a command run within the database container. If for whatever reason you need to override this you can do that by specifying it as follows:

 plugins {
   id("com.revolut.jooq-docker")
 }
 
 
 jooq {
    image {
        readinessProbeHost = "someHost"
    }
 }

jooq-plugin's People

Contributors

adrianskrobaczrevolut avatar capitaorev avatar nonomagic avatar schmist avatar szaffarano avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

jooq-plugin's Issues

Add automatically generated classes to a SourceSet.

Maybe I'm missing something but, after the generation the following block has to be included in order to use the jooq generated classes:

sourceSets {
    main.java.srcDirs += project.layout.buildDirectory.dir("generated-jooq")

}

It might be good if the plugin allowed an option to specify the sourceSet where those classes should be included, setting main.java as a default if the java plugin is included as well.

MySQL 5.7 on Apple Silicon throws "no matching manifest for linux/arm64/v8 in the manifest list entries"

Hi,

As described here the issue is resolved adding a new parameter platform: linux/x86_64.

The changes are adding "platform" variable to the Image class and propagate the value to Docker class to use it in:

private fun startContainer() {
        val dbPort = ExposedPort.tcp(portBinding.first)
        docker.createContainerCmd(imageName)
                .withPlatform(platform)
                .withName(containerName)
                .withEnv(env.map { "${it.key}=${it.value}" })
                .withExposedPorts(dbPort)
                .withHostConfig(newHostConfig().withPortBindings(Ports(dbPort, bindPort(portBinding.second))))
                .exec()
        docker.startContainerCmd(containerName).exec()
}

Thanks

ClassNotFoundException: org.jooq.codegen.KotlinGenerator

Hello,

Probably it is problem of my configuration, but I can't change generator to Kotlin.

Caused by: java.lang.ClassNotFoundException: org.jooq.codegen.KotlinGenerator
        at org.jooq.codegen.GenerationTool.loadClass(GenerationTool.java:926)
        at org.jooq.codegen.GenerationTool.run0(GenerationTool.java:377)
        at org.jooq.codegen.GenerationTool.run(GenerationTool.java:222)
        at com.revolut.jooq.GenerateJooqClassesTask.generateJooqClasses(GenerateJooqClassesTask.kt:186)

Gradle configuration

tasks {
    generateJooqClasses {
        basePackageName = "com.test.infrastructure.database.jooq"
        inputDirectory.setFrom(project.files("src/main/resources/db/migration"))
        outputDirectory.set(project.layout.buildDirectory.dir("generated-jooq"))
        excludeFlywayTable = true
        customizeGenerator {
            name = "org.jooq.codegen.KotlinGenerator"
        }
    }
}

Any idea what could be the problem?

Regards
Patryk

Plugin does not run with JDK 13

Running this plugin under JDK 13 results in the following:

Error during callback
java.net.SocketException: Cannot find method "setCreated" in java.net.Socket. Unsupported JVM?
        at org.newsclub.net.unix.NativeUnixSocket.setCreated(Native Method)
        at org.newsclub.net.unix.AFUNIXSocket.setIsCreated(AFUNIXSocket.java:54)
        at org.newsclub.net.unix.AFUNIXSocket.<init>(AFUNIXSocket.java:48)
        at org.newsclub.net.unix.AFUNIXSocket.newInstance(AFUNIXSocket.java:77)
        at org.newsclub.net.unix.AFUNIXSocket.newInstance(AFUNIXSocket.java:72)
        at com.github.dockerjava.jaxrs.ApacheUnixSocket.<init>(ApacheUnixSocket.java:51)
        at com.github.dockerjava.jaxrs.UnixConnectionSocketFactory.createSocket(UnixConnectionSocketFactory.java:66)
        at org.apache.http.impl.conn.DefaultHttpClientConnectionOperator.connect(DefaultHttpClientConnectionOperator.java:119)
        at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.connect(PoolingHttpClientConnectionManager.java:373)
        at org.apache.http.impl.execchain.MainClientExec.establishRoute(MainClientExec.java:394)
        at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:237)
        at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:185)
        at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:89)
        at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:110)
        at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:185)
        at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:72)
        at org.glassfish.jersey.apache.connector.ApacheConnector.apply(ApacheConnector.java:450)
        at org.glassfish.jersey.client.ClientRuntime.invoke(ClientRuntime.java:278)
        at org.glassfish.jersey.client.JerseyInvocation.lambda$invoke$1(JerseyInvocation.java:767)
        at org.glassfish.jersey.internal.Errors.process(Errors.java:316)
        at org.glassfish.jersey.internal.Errors.process(Errors.java:298)
        at org.glassfish.jersey.internal.Errors.process(Errors.java:229)
        at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:414)
        at org.glassfish.jersey.client.JerseyInvocation.invoke(JerseyInvocation.java:765)
        at org.glassfish.jersey.client.JerseyInvocation$Builder.method(JerseyInvocation.java:456)
        at org.glassfish.jersey.client.JerseyInvocation$Builder.post(JerseyInvocation.java:357)
        at com.github.dockerjava.jaxrs.async.POSTCallbackNotifier.response(POSTCallbackNotifier.java:29)
        at com.github.dockerjava.jaxrs.async.AbstractCallbackNotifier.call(AbstractCallbackNotifier.java:50)
        at com.github.dockerjava.jaxrs.async.AbstractCallbackNotifier.call(AbstractCallbackNotifier.java:24)
> Task :generateJooqClasses FAILED

This is due to a dependency on an outdated version of the docker-java plugin; see docker-java/docker-java#1245. Bumping the dependency to at least 3.2.0 should fix the problem.

Thanks!

JDBC URL host is hardcoded - breaks in non-local Docker setups

Hi,
Firstly, thanks for the nice plugin - this wraps up the tools so neatly!

I've encountered an issue which is unfortunately a blocker in our CI environment: the JDBC URL host is hardcoded to 127.0.0.1. Sadly our CI environment exposes the docker host at a different address - we have a slightly complicated DinD setup that makes this so, although the problem would also occur for users who run Docker on a different host to their CI workers.

I can think of a couple of possible ways around this:

  1. allow HOST to be set via configuration or an environment variable (easiest, least preferable as a user)
  2. derive HOST from DOCKER_HOST (if set, and of scheme tcp/http/https)
  3. for full DinD-friendliness, derive HOST from both DOCKER_HOST and detected DinD state. The most comprehensive, battle-tested code I know of to do this is in testcontainers-java's DockerClientConfigUtils (full disclosure - I'm a maintainer!)

I suspect that the most pragmatic approach would be (2), but would be keen to get your thoughts on this and to hear whether you'd like a PR.

ForcedType not found in Groovy dialect

I'm trying to add a custom type converter as indicated in the README but have run in to a problem.

My build.gradle looks like the following:

plugins {
    id "com.revolut.jooq-docker" version "0.3.3"
}
...
tasks {
    generateJooqClasses {
        customizeGenerator {
            database.withForcedTypes(
                ForcedType()
                    .withUserType("java.time.Instant")
                    .withConverter("...TimestampConverter")
                    .withTypes("TIMESTAMP( WITHOUT TIME ZONE)?")
            )
        }
    }
}

When I attempt to run the generate task, I get the following error:

No signature of method: build_3hd7l9zm5ag6m21i0yljprvyg$_run_closure10$_closure23$_closure24.ForcedType() is applicable for argument types: () values: []

Thus it does not find ForcedType.

How do I get this to work?

Please note that switching to the Kotlin dialect is infeasible in my case for the time being.

NoClassDefFoundError on Windows

First of all thanks very much for this plugin!

I originally ran the build on a Mac, with no issues. But on Windows, a 'NoClassDefFoundError` is being thrown. I'll include the stack trace below.

It seems to me that the problem is happening within docker-java, for some reason it's decided to create a UnixSocketFactory despite being on a Windows machine. I've tested with:

Docker Engine: v20.10.6
JDK 16.0.1
Gradle 6.7

java.lang.NoClassDefFoundError: Could not initialize class com.github.dockerjava.transport.DomainSocket
    at com.github.dockerjava.okhttp.UnixSocketFactory.createSocket(UnixSocketFactory.java:21)
    at okhttp3.internal.connection.RealConnection.connectSocket(RealConnection.java:257)
    at okhttp3.internal.connection.RealConnection.connect(RealConnection.java:183)
    at okhttp3.internal.connection.ExchangeFinder.findConnection(ExchangeFinder.java:224)
    at okhttp3.internal.connection.ExchangeFinder.findHealthyConnection(ExchangeFinder.java:108)
    at okhttp3.internal.connection.ExchangeFinder.find(ExchangeFinder.java:88)
    at okhttp3.internal.connection.Transmitter.newExchange(Transmitter.java:169)
    at okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.java:41)
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:142)
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:117)
    at okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.java:94)
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:142)
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:117)
    at okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.java:93)
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:142)
    at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.java:88)
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:142)
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:117)
    at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:229)
    at okhttp3.RealCall.execute(RealCall.java:81)
    at com.github.dockerjava.okhttp.OkDockerHttpClient$OkResponse.<init>(OkDockerHttpClient.java:256)
    at com.github.dockerjava.okhttp.OkDockerHttpClient.execute(OkDockerHttpClient.java:230)
    at com.github.dockerjava.core.DefaultInvocationBuilder.execute(DefaultInvocationBuilder.java:228)
    at com.github.dockerjava.core.DefaultInvocationBuilder.delete(DefaultInvocationBuilder.java:56)
    at com.github.dockerjava.core.exec.RemoveContainerCmdExec.execute(RemoveContainerCmdExec.java:28)
    at com.github.dockerjava.core.exec.RemoveContainerCmdExec.execute(RemoveContainerCmdExec.java:11)
    at com.github.dockerjava.core.exec.AbstrSyncDockerCmdExec.exec(AbstrSyncDockerCmdExec.java:21)
    at com.github.dockerjava.core.command.AbstrDockerCmd.exec(AbstrDockerCmd.java:35)
    at com.github.dockerjava.core.command.RemoveContainerCmdImpl.exec(RemoveContainerCmdImpl.java:67)
    at com.revolut.jooq.Docker.removeContainer(Docker.kt:86)
    at com.revolut.jooq.Docker.runInContainer(Docker.kt:40)
    at com.revolut.jooq.GenerateJooqClassesTask.generateClasses(GenerateJooqClassesTask.kt:152)

Change docker port?

I wrote a bunch of flaky gradle DSL to do what your plugin does, and I'm hoping to delete it all.

But I'm not getting very far. How do I customize docker options, for instance change the docker host to localhost:2376, or set the network mode to host, so the whole build can run within a Jenkins docker container?

generateJooqClasses is unstable when running on MacOS with Rancher Desktop/Colima

When running the build on MacOS with Rancher Desktop/Colima we are getting occasional connection refused errors, full Gradle log below:

16:21:53: Executing 'generateJooqClasses'...

Starting Gradle Daemon...
Gradle Daemon started in 524 ms
127.0.0.1:5432 - no response
waiting for db
127.0.0.1:5432 - accepting connections
> Task :generateJooqClasses FAILED
1 actionable task: 1 executed

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':generateJooqClasses'.
> 
  Unable to obtain connection from database (jdbc:postgresql://localhost:57409/postgres) for user 'postgres': Connection to localhost:57409 refused. Check that the hostname and port are correct and that the postmaster is accepting TCP/IP connections.
  --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  SQL State  : 08001
  Error Code : 0
  Message    : Connection to localhost:57409 refused. Check that the hostname and port are correct and that the postmaster is accepting TCP/IP connections.


* Try:
> Run with --stacktrace option to get the stack trace.
> Run with --info or --debug option to get more log output.
> Run with --scan to get full insights.

* Get more help at https://help.gradle.org

BUILD FAILED in 10s
16:22:05: Execution finished 'generateJooqClasses'.

The error is intermittent and is only reproducible with a combination of Rancher Desktop/Colima and MacOS (not observed when running the build on our Linux build agents or when running with Docker Desktop).

I believe that the root cause is distinctly related to this issue: rancher-sandbox/rancher-desktop#2609 which is solved by .waitingFor(Wait.forListeningPort())), so assuming there should be a way to construct a jooq.image.readinessProbe in a way that would solve the issue, but I need some advice on how to do that.

Here is our build.gradle.kts configuration:

tasks.generateJooqClasses {
    schemas = arrayOf("public")
    basePackageName = "com.our.base.package"
    outputDirectory.set(jooqOutputPath)
    excludeFlywayTable = true
    outputSchemaToDefault = setOf("public")

    customizeGenerator {
        name = org.jooq.codegen.KotlinGenerator::class.java.name
    }
}

Any advice is greatly appreciated.

having an empty generate object available that can be customized in the generator

Hi, what do you think about adding org.jooq.meta.jaxb.Generate () to the pre-configured set of domain object, even if you don't do anything with it.

It would make the configuration on client side look a bit more consistent.

        customizeGenerator {
            withGenerate (org.jooq.meta.jaxb.Generate().withXXX ())
            database.withXXX ()
        }

Cheers

Plugin is incompatible with Micronaut Gradle plugin

I'm not sure if this is a jooq-plugin problem or a Micronaut one, but the two don't play nicely together.

Minimal build file:

plugins {
  id("com.revolut.jooq-docker") version "0.3.5"
  id("io.micronaut.application") version "1.2.0"
}

group = "com.example"
version = "0.1-SNAPSHOT"

repositories {
  jcenter()
}

micronaut {
  version("2.2.0")
  runtime("netty")
}

application {
  mainClass.set("com.example.Application")
}

This causes Gradle to throw an exception java.lang.NoSuchMethodError: 'com.fasterxml.jackson.databind.ObjectMapper com.github.dockerjava.core.DockerClientConfig.getObjectMapper()'. Full stack trace is at https://gist.github.com/sgrimm/e9d4e9fca6571b339f8a6ae404dd3445 .

The symptom really looks like maybe different versions of different jars in the Java Docker library are being used, but gradle buildEnvironment doesn't show that library as a dependency of the Micronaut plugin. I also tried forcing it to a specific version using setForcedModules() but that didn't help.

Make flyway and jooq versions configurable.

Hi, it would be great if the versions of the flyway and jooq plugins could be taken from either:

  • Configuration properties in the gradle.properties file.
  • From the declared plugins in the plugins, pluginManagement or buildscript blocks.
  • Letting them be handled by a dependency manager (like the spring.dependency-management plugin or via the pluginManagement.

What do you think?

Support multiple datasource to generate jooq classes

Hey,
Thanks for the plugin. It's very useful.

Can you please add a support for multiple datasource configuration? I use two different database in my project so want to generate jooq classes for both of them.

Thanks!

Manual version update of jooq and flyway

Hey,

can see that you are working on a way to make this configurable in #10. Is there any change to get an updated version for jooq and flyway in the meantime?

Not asking for a particular change in any of the libraries, but they have done quite some work over the last iterations

https://flywaydb.org/documentation/learnmore/releaseNotes
https://www.jooq.org/notes

https://mvnrepository.com/artifact/org.flywaydb/flyway-core/7.5.0
https://mvnrepository.com/artifact/org.jooq/jooq/3.14.4

Many thanks in advance.

Plugin fails to download docker image from "index.docker.io"

Realised that the issue relates to Docker Client and the way of how it downloads images from repository not related specifically to this plugin.

Error during callback
com.github.dockerjava.api.exception.InternalServerErrorException: Status 500: unknown image in /images/create?fromImage=postgres%3A14.5-alpine

        at com.github.dockerjava.core.DefaultInvocationBuilder.execute(DefaultInvocationBuilder.java:247)
        at com.github.dockerjava.core.DefaultInvocationBuilder.lambda$executeAndStream$1(DefaultInvocationBuilder.java:269)
        at [email protected]/java.lang.Thread.run(Thread.java:833)

Sourcesets not correctly set (>0.2.5)

On a fairly new codebase where I'm using this plugin, I've encountered what seems like a regression in versions greater than 0.2.5.

It would appear that after this version the sourcesets and compileJava dependency on generateJooqClasses are no longer automatically set up correctly: what I've observed is:

  • generateJooqClasses not being run at all in a normal build (e.g. clean check). This can be worked around by adding compileJava.dependsOn(generateJooqClasses) to the build script.

Following that workaround, it's still not good news:

  • Compilation failures in main code that depends on any generated classes
  • IDE no longer detects the build/generated-jooq directory as a source directory

I've not had time to dig into why this is happening, but for me both of the following workarounds work:

  • Stick with v0.2.5 of the plugin
    or
  • Add the following to build.gradle:
compileJava.dependsOn(generateJooqClasses)

sourceSets {
    jooq {
        java {
            srcDirs "${buildDir}/generated-jooq"
            compileClasspath += main.compileClasspath
            runtimeClasspath += main.runtimeClasspath
        }
    }
    main {
        java {
            compileClasspath += jooq.output
            runtimeClasspath += jooq.output
        }
    }
    test {
        java {
            compileClasspath += jooq.output
            runtimeClasspath += jooq.output
        }
    }
}

I can put together a repro example if you'd like, but before I do so, does anything spring to mind?

Plugin gets stuck or fails when applied in same project with Spring Boot plugin 2.3.0

Hi, after updating Spring Boot to version 2.3.0 in one of my existing project with this plugin i received interesting behaviour that depends on OS (in Linux it's fails generateJooqClasses task, but in MacOS X it gets stuck indefinitely).

To demonstrate this issue i created repository - https://github.com/agpopikov/jooq-plugin-bug-example. This repo contains example that fails when run ./gradlew clean generateJooqClasses build command.

After some investigation i found that after update of Spring Boot plugin (or docker-java as part of plugin) sends different (and obviously incorrect) payload to docker daemon when tries to create container, below example of request with payload:

5 > POST unix://localhost:80/containers/create?name=jooq-docker-container-jooq-plugin-bug-example
5 > Accept: application/json
5 > Content-Type: application/json
{"name":"jooq-docker-container-jooq-plugin-bug-example","authConfig":null,"links":[],"binds":[],"memory":null,"memorySwap":null,"networkMode":null,"portBindings":{"bindings":{"5432/tcp":[{"hostIp":null,"hostPortSpec":"43756"}]}},"privileged":null,"volumesFrom":null,"publishAllPorts":null,"extraHosts":null,"capAdd":null,"capDrop":null,"blkioWeight":null,"cgroupParent":null,"cpuPeriod":null,"cpuShares":null,"cpusetCpus":null,"cpusetMems":null,"devices":null,"dns":null,"dnsSearch":null,"logConfig":{"type":null,"config":null},"lxcConf":null,"oomKillDisable":null,"pidMode":null,"readonlyRootfs":null,"restartPolicy":null,"ulimits":null,"Hostname":null,"Domainname":null,"User":null,"AttachStdin":null,"AttachStdout":null,"AttachStderr":null,"PortSpecs":null,"Tty":null,"OpenStdin":null,"StdinOnce":null,"Env":["POSTGRES_USER=postgres","POSTGRES_PASSWORD=postgres","POSTGRES_DB=postgres"],"Cmd":null,"Healthcheck":null,"ArgsEscaped":null,"Entrypoint":null,"Image":"postgres:11.2-alpine","Volumes":{"volumes":[]},"WorkingDir":null,"MacAddress":null,"OnBuild":null,"NetworkDisabled":null,"ExposedPorts":{"exposedPorts":[{"protocol":"TCP","port":5432,"scheme":"tcp"}]},"StopSignal":null,"StopTimeout":null,"HostConfig":{"binds":[],"blkioWeight":null,"blkioWeightDevice":null,"blkioDeviceReadBps":null,"blkioDeviceWriteBps":null,"blkioDeviceReadIOps":null,"blkioDeviceWriteIOps":null,"memorySwappiness":null,"nanoCPUs":null,"capAdd":null,"capDrop":null,"containerIDFile":null,"cpuPeriod":null,"cpuRealtimePeriod":null,"cpuRealtimeRuntime":null,"cpuShares":null,"cpuQuota":null,"cpusetCpus":null,"cpusetMems":null,"devices":null,"deviceCgroupRules":null,"deviceRequests":null,"diskQuota":null,"dns":null,"dnsOptions":null,"dnsSearch":null,"extraHosts":null,"groupAdd":null,"ipcMode":null,"cgroup":null,"links":[],"logConfig":{"type":null,"config":null},"lxcConf":null,"memory":null,"memorySwap":null,"memoryReservation":null,"kernelMemory":null,"networkMode":null,"oomKillDisable":null,"init":null,"autoRemove":null,"oomScoreAdj":null,"portBindings":{"bindings":{"5432/tcp":[{"hostIp":null,"hostPortSpec":"43756"}]}},"privileged":null,"publishAllPorts":null,"readonlyRootfs":null,"restartPolicy":null,"ulimits":null,"cpuCount":null,"cpuPercent":null,"ioMaximumIOps":null,"ioMaximumBandwidth":null,"volumesFrom":null,"mounts":null,"pidMode":null,"isolation":null,"securityOpts":null,"storageOpt":null,"cgroupParent":null,"volumeDriver":null,"shmSize":null,"pidsLimit":null,"runtime":null,"tmpFs":null,"utSMode":null,"usernsMode":null,"sysctls":null,"consoleSize":null,"userDefinedNetwork":false},"Labels":null,"Shell":null,"NetworkingConfig":null}

And here for example of request and payload from working version of setup:

4 > POST unix://localhost:80/containers/create?name=jooq-docker-container-jooq-plugin-bug-example
4 > Accept: application/json
4 > Content-Type: application/json
{"name":"jooq-docker-container-jooq-plugin-bug-example","Env":["POSTGRES_USER=postgres","POSTGRES_PASSWORD=postgres","POSTGRES_DB=postgres"],"Image":"postgres:11.2-alpine","Volumes":{},"ExposedPorts":{"5432/tcp":{}},"HostConfig":{"PortBindings":{"5432/tcp":[{"HostIp":"","HostPort":"35032"}]}}}

After analysing build environment dependency tree i found that new version of Spring Boot override some dependencies versions (jackson related packages was updated to 2.11.x version instead of 2.10.x).

I think that problem doesn't have elegant solution here at this time (initial problem may contains in docker-java and can't be fixed here without shadowing of broken dependency), but this issue should be actual when docker-java release fix and here it should be updated.

Jooq-Docker conflicts with the Flyway plugin

com.revolut.jooq-docker depends on the old org.flywaydb:flyway-core:6.4.3 version, which is causing the following warnings during the build time:

> Task :generateJooqClasses
Flyway upgrade recommended: PostgreSQL 14.5 is newer than this version of Flyway and support has not been tested. The latest supported version of PostgreSQL is 12.

Suggested resolution: upgrade the flyway-core dependency to a latest version (9.14.1 as of now).

Fails for Postgres as postgres:11.2-alpine is not present in Docker Hub anymore

I am trying to use the latest version of the plugin with Postgres and get this error while Docker service is running:

Execution failed for task ':generateJooqClasses'.

Status 500: unknown image in /images/create?fromImage=postgres%3A11.2-alpine

Running verification/test target in the jooq-plugin project produces a similar error.

Image postgres:11.2-alpine is not present on the Docker hub anymore...
I guess because of critical security issues https://snyk.io/test/docker/postgres%3A11.2-alpine

JNA issue in M1 architecture

It seems that due to this issue M1 architectures are not able to use the plugin, getting the following error

Caused by: java.lang.NoClassDefFoundError: Could not initialize class com.github.dockerjava.transport.DomainSocket                                         
        at com.github.dockerjava.okhttp.UnixSocketFactory.createSocket(UnixSocketFactory.java:21)                                                          
        at okhttp3.internal.connection.RealConnection.connectSocket(RealConnection.java:257)                                                               
        at okhttp3.internal.connection.RealConnection.connect(RealConnection.java:183)                                                                     
        at okhttp3.internal.connection.ExchangeFinder.findConnection(ExchangeFinder.java:224)                                                              
        at okhttp3.internal.connection.ExchangeFinder.findHealthyConnection(ExchangeFinder.java:108)                                                       
        at okhttp3.internal.connection.ExchangeFinder.find(ExchangeFinder.java:88)                                                                         
        at okhttp3.internal.connection.Transmitter.newExchange(Transmitter.java:169)                                                                       
        at okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.java:41)                                                            
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:142)                                                               
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:117)                                                               
        at okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.java:94)                 

Bumping docker-java-transport-okhttp fixes the issue

-    implementation("com.github.docker-java:docker-java-transport-okhttp:3.2.8")
+    implementation("com.github.docker-java:docker-java-transport-okhttp:3.2.14")

As a workaround, it's possible to "override" this dependency (as well as commons-lang)

buildscript {
    configurations.classpath {
        resolutionStrategy {
            setForcedModules("org.jooq:jooq-codegen:3.14.3")
        }
    }

    dependencies {
       classpath("com.github.docker-java:docker-java-transport-okhttp:3.2.14")
       classpath("commons-lang:commons-lang:2.6")
    }
}

jooq-plugin is not compatible with new org.jooq:jooq-codegen:3.17.2

Hello, I'm trying to update the jooq version to 3.17.2 and I'm facing this error

An exception occurred applying plugin request [id: 'com.revolut.jooq-docker', version: '0.3.7']
> Failed to apply plugin 'com.revolut.jooq-docker'.
   > Could not create task ':generateJooqClasses'.
      > Could not create task of type 'GenerateJooqClassesTask'.
         > Could not generate a decorated class for type GenerateJooqClassesTask.
            > org/jooq/meta/jaxb/Generator has been compiled by a more recent version of the Java Runtime (class file version 61.0), this version of the Java Runtime only recognizes class file versions up to 55.0

libs used:
"org.jooq:jooq-codegen:3.17.2"
"org.jooq:jooq:3.17.2"

Support a feature flag to disable generating unchanged files

Every-time I generate JOOQ using the plugin, it generates unnecessary changes with new date and serialVersionUid.

These changes are superficial and I always end up inspecting them one by one and discarding them.

I am requesting a feature flag. When enabled, it would avoid generating these files (that has no real changes) and as a result wouldn't need committed.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.