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

[REQ] Migrate off of com.google.code.findbugs:jsr305 or make it configurable #7177

Open thokuest opened 4 years ago

thokuest commented 4 years ago

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

Pull request #3409 added nullable annotations to generated Java POJOs. The annotations are provided by library com.google.code.findbugs:jsr305. I'd like to cite SpotBugs issue #130 for why I think this is a problem for applications:

JSR-305 is dormant, has been for a long while and shows no hope of ever producing an agreed set of annotations in our lifetime. Further more these annotations use javax. packages which it is not possible to use according to the Oracle Java binary licence, so applications can not use and ship these dependencies along with a JRE without violating the Oracle licence agreement.

F. JAVA TECHNOLOGY RESTRICTIONS. You may not create, modify, or change the behavior of, or authorize your licensees to create, modify, or change the behavior of, classes, interfaces, or subpackages that are in any way identified as "java", "javax", "sun", “oracle” or similar convention as specified by Oracle in any naming convention designation.

The JSR-305 group has not defined any official releases according to its jsr page so the only implementations is a seemingly random implementation provided by the FindBugs team. Even if the team where experts on the JSR (which some where) they are not official as there has been no vote and are not available from the JSR hompage - so the javax package name restriction still applies.

Additionally, using the library with the Java Platform Module System results in a split package and the application won't compile.

Describe the solution you'd like

Make it configurable so that annotations can be enabled/disabled explicitly. Also consider moving to a friendlier alternative. The Kotlin Java Interop Documentation enumerates some options.

Describe alternatives you've considered

/

Additional context

SarvagyaGupta commented 3 years ago

@thokuest Is there any update on this issue?

wing328 commented 3 years ago

One way is to use customized templates (e.g. via the -t CLI option). Please give it a try.

SarvagyaGupta commented 3 years ago

Hi @wing328 , I am pretty new to this. So if I want to remove the annotation, how would I do so? Is there some documentation that you can point me to?

CMoH commented 2 years ago

I've also run into this problem. I want to remove the annotation from the generated code, or provide a custom annotation instead of javax.annotation.Nullable

Cs4r commented 7 months ago

I've also run into this problem. I want to remove the annotation from the generated code, or provide a custom annotation instead of javax.annotation.Nullable

@CMoH did you find a fix for this?

CMoH commented 7 months ago

I've also run into this problem. I want to remove the annotation from the generated code, or provide a custom annotation instead of javax.annotation.Nullable

@CMoH did you find a fix for this?

I had a problem running the generated code within OSGi, so I used the following bundle as maven dependency:

            <dependency>
                <groupId>org.apache.servicemix.bundles</groupId>
                <artifactId>org.apache.servicemix.bundles.jsr305</artifactId>
                <version>3.0.2_1</version>
            </dependency>
Cs4r commented 7 months ago

t

I've also run into this problem. I want to remove the annotation from the generated code, or provide a custom annotation instead of javax.annotation.Nullable

@CMoH did you find a fix for this?

I had a problem running the generated code within OSGi, so I used the following bundle as maven dependency:

            <dependency>
                <groupId>org.apache.servicemix.bundles</groupId>
                <artifactId>org.apache.servicemix.bundles.jsr305</artifactId>
                <version>3.0.2_1</version>
            </dependency>

that isn't a solution, it only references com.google.code.findbugs:jsr305:2.0.0 you can see it here

CMoH commented 7 months ago

t

I've also run into this problem. I want to remove the annotation from the generated code, or provide a custom annotation instead of javax.annotation.Nullable

@CMoH did you find a fix for this?

I had a problem running the generated code within OSGi, so I used the following bundle as maven dependency:

            <dependency>
                <groupId>org.apache.servicemix.bundles</groupId>
                <artifactId>org.apache.servicemix.bundles.jsr305</artifactId>
                <version>3.0.2_1</version>
            </dependency>

that isn't a solution, it only references com.google.code.findbugs:jsr305:2.0.0 you can see it here

You are correct. I ran into this problem when attempting to use the code in OSGi, so I applied this bundle switch as a workaround to the derived problem. I did not attempt to fix the root problem, i.e. the annoying annotation.

In these situations, I usually clone the offending project, develop my patch and submit it to the project devs. Since my own work does not afford to wait, I deploy a patched build to a local maven repo, perhaps using a different group ID, and use that while they debate the patch. Maybe you will find this idea helpful.

Cs4r commented 7 months ago

@CMoH, in order to fix the issue what I have done is the following:

Actual code:

Mvn plugin config

<plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>exec-maven-plugin</artifactId>
    <version>3.2.0</version>
    <executions>
        <execution>
            <id>post-process</id>
            <phase>process-sources</phase>
            <goals>
                <goal>exec</goal>
            </goals>
            <configuration>
                <executable>python3</executable>
                <arguments>
                        <argument>${project.basedir}/post_process_actions.py</argument>
                </arguments>
            </configuration>
        </execution>
    </executions>
</plugin>

Python script

import os
import re

def remove_non_standard_javax_annotations():
    directory = "target/generated-sources/openapi/src/main/java/[YOUR_PACKAGE]"
    for root, dirs, files in os.walk(directory):
        for file in files:
            if file.endswith(".java"):
                filepath = os.path.join(root, file)
                with open(filepath, "r") as f:
                    content = f.read()
                # Remove @javax.annotation.* annotations (non-standard)
                content = re.sub(r'(@javax\.annotation\..*?)\n', '', content)
                content = re.sub(r'@javax\.annotation\..*?\s+', '', content)
                with open(filepath, "w") as f:
                    f.write(content)
CMoH commented 7 months ago

We also had some post-processing tasks to cleanup unwanted files from generated sources. However, we relied on maven-antrun-plugin, which keeps the build confined to the Java world:

            <plugin>
                <artifactId>maven-antrun-plugin</artifactId>
                <groupId>org.apache.maven.plugins</groupId>
                <version>1.7</version>
                <executions>
                    <execution>
                        <id>remove-swagger-codegen-files</id>
                        <phase>generate-sources</phase>
                        <goals>
                            <goal>run</goal>
                        </goals>
                        <configuration>
                            <target>
                                <delete file="${project.build.directory}/generated-sources/openapi/pom.xml"/>
                                <delete file="${project.build.directory}/generated-sources/openapi/README.md"/>
                                <delete file="${project.build.directory}/generated-sources/openapi/build.gradle"/>
                                <delete file="${project.build.directory}/generated-sources/openapi/settings.gradle"/>
                                <delete file="${project.build.directory}/generated-sources/openapi/gradle.properties"/>
                                <delete dir="${project.build.directory}/generated-sources/openapi/gradle"/>
                                <delete file="${project.build.directory}/generated-sources/openapi/gradlew"/>
                                <delete file="${project.build.directory}/generated-sources/openapi/gradlew.bat"/>
                                <delete file="${project.build.directory}/generated-sources/openapi/.gitignore"/>
                                <delete file="${project.build.directory}/generated-sources/openapi/git_push.sh"/>
                                <delete file="${project.build.directory}/generated-sources/openapi/.travis.yml"/>
                                <delete dir="${project.build.directory}/generated-sources/openapi/src"/>
                                <delete dir="${project.build.directory}/generated-sources/openapi/docs"/>
                                <delete file="${project.build.directory}/generated-sources/openapi/.swagger-codegen"/>
                                <delete file="${project.build.directory}/generated-sources/openapi/build.sbt"/>
                                <delete file="${project.build.directory}/generated-sources/openapi/annotations"/>
                                <delete dir="${project.build.directory}/generated-sources/openapi/.openapi-generator"/>
                                <delete file="${project.build.directory}/generated-sources/openapi/.openapi-generator-ignore"/>
                            </target>
                        </configuration>
                    </execution>
                </executions>
            </plugin>

If reliance on python or other external tools needs to be avoided, I found some maven plugins that can replace text in files. Also, writing a maven plugin is not hard.

T3rm1 commented 3 months ago

@wing328 I think it would be a good solution to either remove the findbugs dependency (and its annoations) all together or at least make it opt-in. We shouldn't have to work around this issue by either post processing or using custom templates. These annotations were questionable the whole time and by now it's been stated by various people that it's not recommend to use them any more.

I hope we can move forward here.

T3rm1 commented 4 days ago

@wing328 Reminder

wing328 commented 4 days ago

cc Java technical committee to see if they've an opinion on this:

@bbdouglas (2017/07) @sreeshas (2017/08) @jfiala (2017/08) @lukoyanov (2017/09) @cbornet (2017/09) @jeff9finger (2018/01) @karismann (2019/03) @Zomzog (2019/04) @lwlee2608 (2019/10) @martin-mfg (2023/08)

martin-mfg commented 5 hours ago

TL;DR

I propose switching to SpotBugs' @Nullable annotation. If this doesn't match your needs, please let us know.

Why?

Switching to annotations from a different dependency solves the problems cited by @thokuest, while still allowing us to generate annotated code. I am not sure which of the various alternatives to com.google.code.findbugs.jsr305 we should use - I proposed spotbugs simply because I think it is well established. If anyone has good reasons to suggest a different alternative, please let us know. Since switching to an alternative dependency should solve all cited problems, I don't see a reason to disable the generation of @Nullable annotations. But again, if there is a reason, please let us know. In this case it might make sense to make both changes - switch to spotbugs and also optionally skip the annotation. And finally, if people agree to go with the spotbugs alternative, it would be great if someone could create a PR to implement the change. :)

T3rm1 commented 5 hours ago

I don't see a reason to disable the generation of @Nullable annotations. But again, if there is a reason, please let us know.

Just for the sake of customizability. Let people decide for themselves which dependencies are added to their projects by the generated client. Don't force it. Just like Bean Validation is optional, too.