OpenAPITools / openapi-generator

OpenAPI Generator allows generation of API client libraries (SDK generation), server stubs, documentation and configuration automatically given an OpenAPI Spec (v2, v3)
https://openapi-generator.tech
Apache License 2.0
20.51k stars 6.27k forks source link

[BUG][JAVA][SPRING] No downwards compability (spring 6 to spring 5) of pregenerated client because of new introduced HttpStatusCode #19007

Closed MeckyD closed 3 days ago

MeckyD commented 4 days ago
Description

When trying to use a jar containing a generated client for a Spring Boot 3 service in a Spring 5 project, the application fails to start because of the new introduced HttpStatusCode in Spring 6.

We have many Spring Boot 2.x and now also 3.x services, for which we provide small client jars that can be used by consumers. For that we wrote a small maven plugin that is added to each service, which will start the service, downloads the api-docs, generates the client classes, compiles, builds a jar of it and deploys it to our artifactory. This way we could offer a quick way to use our service in other projects to many consumers, without them needing to do more than adding one dependency.

Now when generating the client jar in a spring boot 3 service, this client cannot be used in any project with an older spring boot / spring version, because every endpoint validation will throw an HttpClientErrorException with the constructor needing a HttpStatusCode (where previously needing a HttpStatus).

When trying to start the consuming application, any class relying to the client will throw the following exception when being instantiated: Constructor threw exception; nested exception is java.lang.NoClassDefFoundError: org/springframework/http/HttpStatusCode

Setting 'useSpringBoot3' to 'true' won't make a difference for this api-break (although it works fine for all other Spring Boot 3 related changes).

openapi-generator version

7.6.0

Code snippets

The generated validation that causes the error

// verify the required parameter 'businessPartnerId' is set
if (businessPartnerId == null) {
        throw new HttpClientErrorException(HttpStatus.BAD_REQUEST, "Missing the required parameter 'businessPartnerId' when calling retrieveAssignmentForBusinessPartner");
}

The constructor of HttpClientErrorException before spring 6

public HttpClientErrorException(HttpStatus statusCode, String statusText) {
        super(statusCode, statusText);
}

The constructor of HttpClientErrorException after spring 6

public HttpClientErrorException(HttpStatusCode statusCode, String statusText) {
        super(statusCode, statusText);
}
Steps to reproduce

Use a pre-generated client in any project with spring version < 6

Related issues/PRs

https://github.com/spring-projects/spring-framework/issues/28214

Suggest a fix

As the api-break is produced by spring, i cannot think of a fix in the openapi-generator plugin, but maybe an parameter could be introduced, which will use a generic Exception instead of the broken HttpClientErrorException for these validations.

MeckyD commented 3 days ago

For anyone running into the same problem: I was able to solve the api-break by adding a property to my self-written plugin, which enables custom templates for the generation with the openapi-generator.

The service using this plugin must then provide own templates in it's resources, containing a customized api.mustache and ApiClient.mustache, where all occurences of the HttpStatusCode are removed (e.g. the HttpClientErrorException replaced by its parent-parent RestClientResponseException, method calls of ResponseEntity.getStatusCode with .getStatusCodeValue, for Exceptions getRawStatusCode instead of getStatusCode and so on...).