since last week (first occurence on 9th of May 2023) our Gradle build of a Micronaut-based application fails with

[...]

> Task :openApiGenerate FAILED
Error snake-parsing yaml content
java.lang.NoSuchMethodError: org.yaml.snakeyaml.constructor.SafeConstructor: method 'void <init>()' not found
        at io.swagger.v3.parser.util.DeserializationUtils$CustomSnakeYamlConstructor.<init>(DeserializationUtils.java:393)
        at io.swagger.v3.parser.util.DeserializationUtils.readYamlTree(DeserializationUtils.java:207)
        at io.swagger.v3.parser.util.DeserializationUtils.deserializeIntoTree(DeserializationUtils.java:143)
        at io.swagger.v3.parser.OpenAPIV3Parser.readContents(OpenAPIV3Parser.java:165)
        at io.swagger.v3.parser.OpenAPIV3Parser.readLocation(OpenAPIV3Parser.java:94)
        at io.swagger.parser.OpenAPIParser.readLocation(OpenAPIParser.java:16)
        at org.openapitools.codegen.config.CodegenConfigurator.toContext(CodegenConfigurator.java:589)
        at org.openapitools.codegen.config.CodegenConfigurator.toClientOptInput(CodegenConfigurator.java:647)
        at org.openapitools.generator.gradle.plugin.tasks.GenerateTask.doWork(GenerateTask.kt:825)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java
        [...]

This project makes use of--among other things--

After investigating some possible root causes, to me it seems to be caused by an incompatible change with 3rd-party lib snakeyaml between its version 1.33 to 2.0, and "cross-usage" of this lib:

Micronaut 3.9.1

makes use of snakeyaml version 2.0, declared in his BOM:

$ ./gradlew dependencyInsight --dependency org.yaml:snakeyaml
[...]

> Task :dependencyInsight
org.yaml:snakeyaml:2.0 (by constraint)
  Variant compile:
    | Attribute Name                     | Provided | Requested         |
    |------------------------------------|----------|-------------------|
    | org.gradle.status                  | release  |                   |
    | org.gradle.category                | library  | library           |
    | org.gradle.libraryelements         | jar      | classes+resources |
    | org.gradle.usage                   | java-api | java-api          |
    | org.gradle.dependency.bundling     |          | external          |
    | org.gradle.jvm.environment         |          | standard-jvm      |
    | org.gradle.jvm.version             |          | 17                |
    | org.jetbrains.kotlin.platform.type |          | jvm               |

org.yaml:snakeyaml:2.0
+--- io.micronaut:micronaut-bom:3.9.1
|    \--- compileClasspath
[...]

** Confirmed by explicitly querying BOM's dependency:

$ curl --silent https://repo1.maven.org/maven2/io/micronaut/micronaut-bom/3.9.1/micronaut-bom-3.9.1.pom | grep snakeyaml
 <snakeyaml.version>2.0</snakeyaml.version>
     <artifactId>snakeyaml</artifactId>
     <version>${snakeyaml.version}</version>

Current version 6.6.0 of Gradle's OpenAPI plugin

makes use of snakeyaml version 1.33; found this by launching Gradle built with --scan option, showing here excerpt of tab "Build (!!!) dependencies":

build.gradle
  com.google.cloud.tools.jib:com.google.cloud.tools.jib.gradle.plugin:3.+ => 3.3.2
  com.gorylenko.gradle-git-properties:com.gorylenko.gradle-git-properties.gradle.plugin:2.+ => 2.4.1
  io.micronaut.application:io.micronaut.application.gradle.plugin:3.+ => 3.7.9
  org.jetbrains.kotlin.jvm:org.jetbrains.kotlin.jvm.gradle.plugin:1.8.21
  org.jetbrains.kotlin.kapt:org.jetbrains.kotlin.kapt.gradle.plugin:1.8.21
  org.jetbrains.kotlin.plugin.allopen:org.jetbrains.kotlin.plugin.allopen.gradle.plugin:1.8.21
  org.openapi.generator:org.openapi.generator.gradle.plugin:6.+ => 6.6.0
    org.openapitools:openapi-generator-gradle-plugin:6.6.0
      org.openapitools:openapi-generator:6.6.0
        com.fasterxml.jackson.core:jackson-databind:2.14.0 => 2.15.0
        com.fasterxml.jackson.datatype:jackson-datatype-guava:2.14.0 => 2.15.0
        com.fasterxml.jackson.datatype:jackson-datatype-joda:2.14.0 => 2.15.0
        com.github.ben-manes.caffeine:caffeine:2.9.3
        com.github.curious-odd-man:rgxgen:1.4
        com.github.jknack:handlebars-jackson2:4.2.1
        com.github.jknack:handlebars:4.2.1
        com.github.joschi.jackson:jackson-datatype-threetenbp:2.12.5
        com.github.mifmif:generex:1.0.2
        com.google.guava:guava:31.1-jre
        com.samskivert:jmustache:1.15
        commons-cli:commons-cli:1.5.0
        commons-io:commons-io:2.11.0
        io.swagger.parser.v3:swagger-parser:2.1.6
          commons-io:commons-io:2.11.0
          io.swagger.parser.v3:swagger-parser-v2-converter:2.1.6
          io.swagger.parser.v3:swagger-parser-v3:2.1.6
          org.yaml:snakeyaml:1.33 => 2.0  // <== HERE!!!
[...]

As far as I can see, there are two options here:

  • Upgrading Gradle's OpenAPI plugin to make use of snakeyaml library version 2.0;
  • Forcing build process to make use of version 1.33 of this lib.

Tried some ways described in Gradle's documentation to for instance force usage of a specific version of transient lib (here version 1.33 of snakeyaml lib), but without success.

Also slight "downgrades" of Micronaut's as well as OpenAPI Generator plugin's versions, but without success.

Any help, idea, hint very appreciated.

Thank you.

Regards

Christian

Further investigation/information:

  • Forcing usage of snakeyaml:1.33 within build.gradle does not fix the problem:

    buildscript {
      repositories {
        mavenCentral()
      }
      dependencies {
        classpath('org.yaml:snakeyaml:1.33')
      }
    }
    
    [...]
    
    configurations {
      micronautBoms {
        resolutionStrategy.force 'org.yaml:snakeyaml:1.33'
      }
    }
    
    [...]
    
    dependencies {
      [...]
      implementation('org.yaml:snakeyaml') {
        version {
          strictly '1.33'
        }
      }
      [...]
    }
    
  • As evaluated above, OpenAPI Generator plugin makes use of io.swagger.parser.v3:swagger-parser:2.1.6 library, which itself declares to make use of snakeyaml library, but without specifying any version restrictions:

    $ curl --silent https://repo1.maven.org/maven2/io/swagger/parser/v3/swagger-parser-v3/2.1.14/swagger-parser-v3-2.1.14.pom | grep -A 1 -B 2 snakeyaml
         <dependency>
             <groupId>org.yaml</groupId>
             <artifactId>snakeyaml</artifactId>
         </dependency>
    

    Maybe explicitly declaring version restriction here (like 1.* or 1.33) would make Gradle recognize conflicting version requirements of this plugin and Micronaut (framework).

0

There are 0 best solutions below