Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BUG] [JAVA] Declaring arrays of ranged integers produces generated java code that fails compilation on 'cannot find symbol' #15213

Closed
5 of 6 tasks
ronkitay opened this issue Apr 13, 2023 · 0 comments · Fixed by #15330

Comments

@ronkitay
Copy link

ronkitay commented Apr 13, 2023

Bug Report Checklist

  • Have you provided a full/minimal spec to reproduce the issue?
  • Have you validated the input using an OpenAPI validator (example)?
  • Have you tested with the latest master to confirm the issue still exists?
  • Have you searched for related issues/PRs?
  • What's the actual output vs expected output?
  • [Optional] Sponsorship to speed up the bug fix or feature request (example)
Description

Starting from version 6.5.0 (id 'org.openapi.generator' version '6.5.0') - the below openapi.yaml produces code that fails compilation.
The scenario is defining an array of integers which have a validation rule defined (I used min/max ranges - there might be other scenarios as well).

The relevant generated method in the interface is:

 default ResponseEntity<String> getDemo(
        @NotNull @Parameter(name = "type", description = "The type of Demo.", required = true, in = ParameterIn.QUERY) @Valid @RequestParam(value = "type", required = true) List<SomeEnum> type,
        @Parameter(name = "rangedValues", description = "The values within ranged.", in = ParameterIn.QUERY) @Valid @RequestParam(value = "rangedValues", required = false) List<@Valid RangedValue> rangedValues
    ) {
        return getDelegate().getDemo(type, rangedValues);
    }

I believe the extra @Valid within the List<... is redundant but have not verified that.

openapi-generator version

The problem occurs in 6.5.0 only, in 6.4.0 it works fine.

OpenAPI declaration file content or url
openapi: "3.0.0"
info:
  title: Demo API
  description: A Demo API
  version: 0.0.1

servers:
  - url: https://localhost:8080/api/1

tags:
  - name: demo
    description: Contains all the demo APIs

components:
  schemas:
    SomeEnum:
      type: string
      enum:
        - value1
        - another-value
        - best_value
        - thevalue

    RangedValueList:
      type: array
      items:
        $ref: "#/components/schemas/RangedValue"

    RangedValue:
      properties:
        value:
          type: integer
          minimum: 5
          maximum: 50

paths:
  /demo:
    get:
      tags:
        - demo
      description: "A demo API"
      operationId: "getDemo"
      parameters:
        - in: query
          name: type
          description: The type of Demo.
          schema:
            type: array
            items:
              $ref: "#/components/schemas/SomeEnum"
          required: true

        - in: query
          name: rangedValues
          description: The values within ranged.
          schema:
            $ref: "#/components/schemas/RangedValueList"
          required: false

      responses:
        "200":
          description: success
          content:
            application/json:
              schema:
                type: string
Generation Details

I recreated the issue with the following gradle setup:

plugins {
	id 'java'
	id 'org.springframework.boot' version '2.7.9'
	id 'io.spring.dependency-management' version '1.0.15.RELEASE'
	
	id 'org.openapi.generator' version '6.5.0'
}

apply plugin: 'org.openapi.generator'

group = 'com.ronkitay'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '1.8'

repositories {
	mavenCentral()
}

dependencies {
	implementation 'org.springframework.boot:spring-boot-starter-web'
	testImplementation 'org.springframework.boot:spring-boot-starter-test'

	implementation 'org.springdoc:springdoc-openapi-ui:1.6.14'
    implementation 'org.openapitools:jackson-databind-nullable:0.2.3'
    implementation 'org.modelmapper:modelmapper:3.0.0'
}

tasks.named('test') {
	useJUnitPlatform()
}

springBoot {
    mainClass = 'com.ronkitay.gradle.springboot.Main'
}

sourceSets {
    main {
        java {
            srcDirs = ['src/main/java', 'build/generated/src/main/java']
        }
    }
}

openApiGenerate {
    generatorName = 'spring'
    inputSpec = "$rootDir/src/main/resources/openapi.yaml".toString()
    outputDir = "$buildDir/generated".toString()
    apiPackage = 'com.ronkitay.openapidemo.api'
    modelPackage = 'com.ronkitay.openapidemo.model'
    invokerPackage = 'com.ronkitay.openapidemo.invoker'

    configOptions = [
            dateLibrary      : 'java8',
            annotationLibrary: 'swagger2',
            delegatePattern  : 'true',
            useTags: 'true',
            additionalEnumTypeAnnotations: '@com.fasterxml.jackson.annotation.JsonFormat'

    ]
}

compileJava.dependsOn tasks.openApiGenerate  

This is the main class in my app:

package com.ronkitay.gradle.springboot;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;

@SpringBootApplication
@ComponentScan(basePackages = {
		"com.ronkitay.openapidemo.invoker",
		"com.ronkitay.gradle.springboot" })
public class Main {

	public static void main(String[] args) {
		SpringApplication.run(Main.class, args);
	}

}

I'm using gradle v8.0.2.

Steps to reproduce

Running the below command triggers the issue:

gradle clean build
Related issues/PRs

Judging by the diffs between 6.4.0 and 6.5.0 and the description of the commit - this seems like a likely culprit:

92b9663

The relevant code seems to be this method:

    private String replaceBeanValidationCollectionType(CodegenProperty codegenProperty, String dataType) {
        if (!useBeanValidation() || !codegenProperty.isModel || isResponseType(codegenProperty)) {
            return dataType;
        }

        if (StringUtils.isEmpty( dataType ) || dataType.contains( "@Valid" )) {
            return dataType;
        }
        return dataType.replace( "<", "<@Valid " );
    }

I am not certain that this is the root cause - but it seems very relevant.

Suggest a fix

See the above related commit - if it is the root cause I do not know how best to fix it as I'm assuming it solves a concrete problem, so removing it will not be enough.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant