Skip to content
New issue

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

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

Already on GitHub? # to your account

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

Closed
MeckyD opened this issue Jun 24, 2024 · 4 comments

Comments

@MeckyD
Copy link

MeckyD commented Jun 24, 2024

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

spring-projects/spring-framework#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
Copy link
Author

MeckyD commented Jun 25, 2024

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...).

@MeckyD MeckyD closed this as completed Jun 25, 2024
@naveenholla
Copy link

Hi @MeckyD , wanted to know what steps you did for working around this bug , can you share some code snippets please

@MeckyD
Copy link
Author

MeckyD commented Oct 4, 2024

Hi @MeckyD , wanted to know what steps you did for working around this bug , can you share some code snippets please

I'm currently on a day off, I will be able to share code snippets on monday.
Until then you might try it yourself by copying the default .mustache templates from openapi-generator and adjust them to your needs.

@MeckyD
Copy link
Author

MeckyD commented Oct 7, 2024

@naveenholla
So first you have to set a custom template directory in your configuration by adding the following property:

<groupId>org.openapitools</groupId>
<artifactId>openapi-generator-maven-plugin</artifactId>
<version>7.8.0</version>
<executions>
  <execution>
    (...)
    <configuration>
      (...)
      <templateDirectory>${basedir}/src/main/resources/http-client-generator-templates</templateDirectory>

In this folder "http-client-generator-templates" you have to provide the to files api.mustache and ApiClient.mustache.

In these files you have to replace all occurrences of the API-break like "response.getStatusInfo().getStatusCode()", i just replaced them with "response.getStatusCodeValue()" and compare them with the raw int.

Example (ApiClient.mustache:823):
if(response.getStatusInfo().getStatusCode() == ClientResponse.Status.NO_CONTENT.getStatusCode()) {
replaced with:
if(response.getStatusInfo().getStatusCodeValue() == 204) {

You might have to run the generation with the custom templates several times until you found all occurrences.

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

No branches or pull requests

2 participants