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
21.86k stars 6.59k forks source link

[REQ] Support SpringBoot 3.0 GA for Java-based API code generation #14143

Closed kpupkov-ppa closed 4 months ago

kpupkov-ppa commented 1 year ago

Is your feature request related to a problem? Please describe.

We need a new way to generate API with jakarta annotations in code

Describe the solution you'd like

all javax.XXXX is no longer supported and replaced by jakarta

Describe alternatives you've considered

no alternative

Additional context

https://spring.io/blog/2022/11/24/spring-boot-3-0-goes-ga

maxl2287 commented 1 year ago

Same here... Code-generation is not possible using Spring Boot 3.0.0 with the latest openapi-generator version...

borsch commented 1 year ago

@kpupkov-ppa @maxl2287 you can use config property useSpringBoot3 to enable SB3 & Jarakta imports

https://github.com/OpenAPITools/openapi-generator/blob/master/docs/generators/spring.md

changes are here - https://github.com/OpenAPITools/openapi-generator/pull/12407/files#diff-9de34b4aad5de707e8aa0c031f20a6573f8f50826a437f0652c54b3788b37d41R434

vigourouxc commented 1 year ago

The same problem applies to the "java" code generator (client side). We're using java with webclient generator, and the templates use javax.annotation packages that are incompatible with a spring boot 3 application.

pstorch commented 1 year ago

@borsch useSpringBoot3 only works for the model classes, but not for the generated restcontroller classes. They are still genereated with javax.annotation.* and javax.validation.* imports.

mlemnian commented 1 year ago

@ComputerDaddyGuy mentioned over in the swagger-codegen github repo the following workaround:

Assuming you are generating your objects inside /src/gen/java/your/package, you can add the following plugin to your pom.xml

<plugin>
    <groupId>com.google.code.maven-replacer-plugin</groupId>
    <artifactId>replacer</artifactId>
    <version>1.5.3</version>
    <executions>
        <execution>
            <phase>generate-sources</phase>
            <goals>
                <goal>replace</goal>
            </goals>
        </execution>
    </executions>
    <configuration>
        <includes>
            <include>${project.basedir}/src/gen/java/**/*.java</include>
        </includes>
        <regex>false</regex>
        <token>javax.annotation</token>
        <value>jakarta.annotation</value>
    </configuration>
</plugin>

You will then see some new logs in your console, after the swagger-codegen-maven-plugin logs:

[INFO] --- replacer:1.5.3:replace (default) @ my-super-api ---
[INFO] Replacement run on 39 files.

source: https://github.com/swagger-api/swagger-codegen/issues/11797#issuecomment-1345156127

The idea is to generate the code as usual but modify it automatically afterward. I'm not a huge fan of this approach but as a workaround, it's "ok".

DennisHartrampf commented 1 year ago

We also need Spring Boot 3.0.0 support for Kotlin-Spring. Should this be a separate issue? Also even useSpringBoot3 (which is not available in Kotlin-Spring) doesn't seem to be the end of the road. It is using Spring Boot 3.0.0-M3 instead of the release version 3.0.0.

DennisHartrampf commented 1 year ago

Never mind. There is already an issue for Kotlin-Spring: #13578.

aleksbal commented 1 year ago

The solution for this problem would be the use of customised mustache templates in your project. Just copy original templates in a project folder and modify some or all of them by replacing "javax" with "jakarta"...

mlemnian commented 1 year ago

@aleksbal IMHO this is not a solution but another workaround. If there are any changes in the mustache templates in this project, you have to backport the changes into your own project as well.

This whole problem could have been handled years ago (since November 2020 the Jakarta EE 9 spec was released). Since then openapi-generator but also the swagger-codegen could have implemented a java/jvm wide toggle/flag to use either a jakarta or javax packages.

Why java/jvm wide? because of

E.g. the spring generator has a useSpringBoot3 that doesn't work in some cases.

To be honest, this is not a great experience.

aleksbal commented 1 year ago

@mlemnian

Well, I think it is legit to use customised mustache templates for code generation in order to solve some specific project needs. However I agree that javax/jakarta problem is not really "the specific one" but rather the one which affects the whole ecosystem.

Since then openapi-generator but also the swagger-codegen could have implemented a java/jvm wide toggle/flag to use either a jakarta or javax packages.

Actually they've bee trying, for example, if you have a look in the templates from OpenAPI generator's Java Spring module (v6.2.1) you will find a flag called "useJakartaEe", which determines whether to generate the Java classes using "javax." or "jakarta."...

borsch commented 1 year ago

@borsch useSpringBoot3 only works for the model classes, but not for the generated restcontroller classes. They are still genereated with javax.annotation. and javax.validation. imports.

@pstorch could you please provide a sample for this? I don't see any javax imports in SB3 generated project

aleksbal commented 1 year ago

I however was not able to utilise the "useJakartaEe", just have seen it in the templates but to set the flag to true or false didn't work for me, so I adjusted the original templates to fit our needs. I would appreciate any example which demonstrates the usability. Thx.

pstorch commented 1 year ago

@borsch mea culpa. I verified it again and the one project which had this issue is using custom templates, which use the javax namespace. :facepalm: Sorry, I didn't see that.

borsch commented 1 year ago
  1. Recently these two MRs were merged with upgrades on SP3 to 3.0.0 & update for SB 2.7.x.
  2. jakarta as for now is available only with SP3 which can be enabled with useSpringBoot3=true option

Any other issues to be covered here? Otherwise make sense to close this one

https://github.com/OpenAPITools/openapi-generator/pull/14283 https://github.com/OpenAPITools/openapi-generator/pull/14285

alwibrm commented 1 year ago

Hi @borsch, when using generator java with library webclient the generated code still contains javax. instead of jakarta., even with the config option <useSpringBoot3>true</useSpringBoot3>. This is a blocker for us to upgrade on Spring Boot 3.

borsch commented 1 year ago

@alwibrm webclient doesn't yet support neither SB3 nor jakarta. This change is in progress

alwibrm commented 1 year ago

@borsch Thanks for the quick reply. Is there an open issue for that or a planned release version/date?

borsch commented 1 year ago

@alwibrm I'm aware only about rest-template update to spring 6 https://github.com/OpenAPITools/openapi-generator/issues/14276

alwibrm commented 1 year ago

@borsch You mentioned the change for webclient was in progress. Is there any issue or merge request for this? Otherwise I would consider contributing a merge request.

parenko commented 1 year ago

FYI: with #14343 it is now possible to enable jakarta namespace for non SB3 Java templates by using useJakartaEe=true.

LSzelecsenyi commented 1 year ago

Hi. I am trying to upgrade our project to spring-boot 3. During this I encountered the javax/jakarta issue. Upgraded the openapi-generator to 6.2.0 and made the setting <useSpringBoot3>true</useSpringBoot3> in the pom.xml but still having problem with javax.ws.rs.core. I am having error "package javax.ws.rs.core does not exist". Any idea how to fix it? Thanks in advance!

mlemnian commented 1 year ago

Hi. I am trying to upgrade our project to spring-boot 3. During this I encountered the javax/jakarta issue. Upgraded the openapi-generator to 6.2.0 and made the setting <useSpringBoot3>true</useSpringBoot3> in the pom.xml but still having problem with javax.ws.rs.core. I am having error "package javax.ws.rs.core does not exist". Any idea how to fix it? Thanks in advance!

@LSzelecsenyi Suppose your application code references the old javax.* classes, you have to rename every occurrence of the name javax to jakarta inside of your code. (and update your maven/gradle dependencies)

If this reference is inside the generated code, this is odd. Spring usually doesn't use a lot of JavaEE/JakartaEE classes/APIs, maybe you don't use the spring (<generatorName>spring</generatorName>) generator at all?

parenko commented 1 year ago

@kpupkov-ppa , could you please try the latest 6.3.0 release if your requiment is met?

LSzelecsenyi commented 1 year ago

@LSzelecsenyi Suppose your application code references the old javax.* classes, you have to rename every occurrence of the name javax to jakarta inside of your code. (and update your maven/gradle dependencies)

If this reference is inside the generated code, this is odd. Spring usually doesn't use a lot of JavaEE/JakartaEE classes/APIs, maybe you don't use the spring (<generatorName>spring</generatorName>) generator at all?

@mlemnian Thanks for the reply. In my code I changed every import to jakarta, the problem is with the generated stuff only. I am using spring in the generator's config. For a temporary fix I am using maven-replacer-plugin to change javax from the generated code

parenko commented 1 year ago

@LSzelecsenyi Suppose your application code references the old javax.* classes, you have to rename every occurrence of the name javax to jakarta inside of your code. (and update your maven/gradle dependencies) If this reference is inside the generated code, this is odd. Spring usually doesn't use a lot of JavaEE/JakartaEE classes/APIs, maybe you don't use the spring (<generatorName>spring</generatorName>) generator at all?

@mlemnian Thanks for the reply. In my code I changed every import to jakarta, the problem is with the generated stuff only. I am using spring in the generator's config. For a temporary fix I am using maven-replacer-plugin to change javax from the generated code

@LSzelecsenyi please try 6.3.0 with configOption <useJakartaEe>true</useJakartaEe>.

LSzelecsenyi commented 1 year ago

@LSzelecsenyi please try 6.3.0 with configOption <useJakartaEe>true</useJakartaEe>.

@parenko I am trying with <useSpringBoot3>true</useSpringBoot3> doc says:

useSpringBoot3: Generate code and provide dependencies for use with Spring Boot 3.x. (Use jakarta instead of javax in imports). Enabling this option will also enable useJakartaEe.

Tried with 6.3.0 but without the replacer I am getting the same error: package javax.ws.rs.core does not exist

pstorch commented 1 year ago

For me it worked with 6.2.1 and 6.3.0 with configOption <useSpringBoot3>true</useSpringBoot3> @LSzelecsenyi can you show your maven/gradle section? Do you use custom templates?

LSzelecsenyi commented 1 year ago

@pstorch

<plugin>
    <groupId>org.openapitools</groupId>
    <artifactId>openapi-generator-maven-plugin</artifactId>
    <version>6.3.0</version>
    <executions>
        <execution>
            <goals>
                <goal>generate</goal>
            </goals>
            <configuration>
                <inputSpec>
                    ${basedir}/src/main/resources/openapi/api.yaml
                </inputSpec>
                <generatorName>spring</generatorName>
                <apiPackage>${project.groupId}.foo.client</apiPackage>
                <modelPackage>${project.groupId}.foo.model</modelPackage>
                <supportingFilesToGenerate>ApiUtil.java</supportingFilesToGenerate>
                <configOptions>
                    <openApiNullable>false</openApiNullable>
                    <useTags>true</useTags>
                    <useSpringBoot3>true</useSpringBoot3>
                    <sourceFolder>src/main/java/</sourceFolder>
                    <delegatePattern>true</delegatePattern>
                    <interfaceOnly>true</interfaceOnly>
                </configOptions>
            </configuration>
        </execution>
    </executions>
</plugin>
alwibrm commented 1 year ago

The config option <useJakartaEe>true</useJakartaEe> in version 6.3.0 for generator java and library webclient now leads to the correct jakarta.* namespaces.

Unfortunately the build is still broken because of a cannot find symbol exception in Schema.RequiredMode.

This is because there are two different versions of swagger-annotations on the classpath, 1.6.8 and 2.2.4:

[INFO] +- org.openapitools:openapi-generator:jar:6.3.0:compile
[INFO] |  +- io.swagger.parser.v3:swagger-parser:jar:2.1.6:compile
[INFO] |  |  +- io.swagger.parser.v3:swagger-parser-v2-converter:jar:2.1.6:compile
[INFO] |  |  |  +- io.swagger:swagger-core:jar:1.6.8:compile
[INFO] |  |  |  |  +- io.swagger:swagger-models:jar:1.6.8:compile
[INFO] |  |  |  |  |  \- io.swagger:swagger-annotations:jar:1.6.8:compile
[INFO] |  |  \- io.swagger.parser.v3:swagger-parser-v3:jar:2.1.6:compile
[INFO] |  |     +- io.swagger.core.v3:swagger-core:jar:2.2.4:compile
[INFO] |  |     |  +- io.swagger.core.v3:swagger-annotations:jar:2.2.4:compile
pstorch commented 1 year ago

@LSzelecsenyi ok, I don't see any obvious mistakes.

parenko commented 1 year ago

@LSzelecsenyi could you also share your api.yaml which causes "package javax.ws.rs.core does not exist"? Currently I cant reproduce the error only with provided plugin configuration.

laidani commented 1 year ago

For feature readers, I solved the issue by adding these dependencies to my project plus <useSpringBoot3>true</useSpringBoot3>:

<dependency>
    <groupId>org.openapitools</groupId>
    <artifactId>jackson-databind-nullable</artifactId>
    <version>0.2.6</version>
</dependency>
<dependency>
    <groupId>jakarta.validation</groupId>
    <artifactId>jakarta.validation-api</artifactId>
    <version>3.0.2</version>
</dependency>
<dependency>
    <groupId>io.swagger.core.v3</groupId>
    <artifactId>swagger-annotations</artifactId>
    <version>2.2.8</version>
</dependency>
aquacode commented 1 year ago

I'm using the https://github.com/int128/gradle-swagger-generator-plugin plugin along with openapi-generator-cli version 6.6.0 and I am also noticing this for: generator: spring library: spring-boot

How are people working around this issue? I seem to have the correct annotations bytecode since my version of Schema on classpath doesn't have the requiredCode property or RequiredMode.

It seems to be a problem with the model code generation using the outdated requiredMode property. Is that a problem in the mustache template? Is there any workaround?

max-kry commented 1 year ago

The workaround ended up being:

ario-afrashteh commented 1 year ago

Any update guys?

frankjkelly commented 1 year ago

Thanks to @laidani I was able to get passed the cannot find symbol on requiredMode = Schema.RequiredMode.REQUIRED by forcibly updating the following

  implementation('io.swagger.core.v3:swagger-annotations:+') {
    because("we get error that we cannot find a symobl on Schema.RequiredMode. See https://github.com/OpenAPITools/openapi-generator/issues/14143 ")
  }
Philzen commented 5 months ago

@kpupkov-ppa correct me if i'm wrong, but as far as i understand code generation for java with spring boot 3 is working fine nowadays … if you agree, kindly close this issue.

tukez commented 4 months ago

There is still problem with the generated controllers which use javax annotation imports.

pstorch commented 4 months ago

@tukez as far es I can see the imports are all fine if you use the useSpringBoot3 option.

tukez commented 4 months ago

@pstorch Thank you, that is correct. It was some Eclipse problem which was corrected once I manually deleted the old generated file (Eclipse clean was not enough for some reason).

Philzen commented 4 months ago

@tukez @kpupkov-ppa as confirmed now, useSpringBoot3 (or only useJakartaEe for that matter) flags do the job.

Closing this issue for now. Should anyone come across a specific java generator that doesn't respect these flags correctly, kindly open a new issue so they can be targeted and fixed in more atomic PRs.