Skip to content

Proposal to change the com.github.johnrengelman.processes gradle process plugin #36

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

Closed
kpramesh2212 opened this issue Dec 3, 2020 · 10 comments

Comments

@kpramesh2212
Copy link
Contributor

Background:

Spring docs open api gradle plugin is used to generate the openapi.json or openapi.yaml file during the build process.

The plugin works as follows

  1. When this plugin is added to the project, it adds the following 2 tasks

    a) forkedSpringBootRun is of type com.github.jengelman.gradle.plugins.processes.tasks.Fork

    b) generateOpenApiDocs

  2. When the user calls the task gradle clean generateOpenApiDocs. The plugin make a call to forkedSpringBootRun task.

  3. forkedSpringBootRun task internally calls the bootJar task (added by the spring boot gradle plugin) and runs it in a separate process

  4. Finally generateOpenApiDocs makes a call to the spring boot apiDocs url which was started by forkedSpringBootRun task to generate the openapi.json or (.yaml) file and then at end shutdowns the forkedSpringBootRun process.

Proposal:

The proposal is to completely remove com.github.johnrengelman.processes plugin and use a much simpler process plugin called com.github.hesch.execfork

Why should we replace?

The following are the reasons to replace com.github.johnrengelman.processes plugin

  1. The plugin is very old and was developed for older versions of gradle. The plugin uses gradle api calls which are now deprecated in the newer versions of the gradle api.

  2. The developer of the plugin has not released any new updates for newer releases of gradle and the plugin seems to be not maintained any more.

  3. Internally we in the springdoc gradle plugin team have few issues which cannot be solved using this com.github.johnrengelman.processes plugin. The following are few examples

    a) The forkedSpringBootRun task is reliant on the bootJar task. This means before we can generate the openapi.json file the spring boot jar needs to be completely build. There are some users who would like to have the openapi.json file added to the spring boot jar. The only way to accomplish this is to rebuild the jar using another gradle task which is not very good approach

    b) Adding JVM arguments and environmental properties we have to write our own logic and expose them as gradle extension properties (see forkProperties). Customizing the boot application becomes complex

    c) The forkedSpringBootRun starts the spring boot application using the system JVM which might not be feasible for many users who might have different JVM in their IDE. In order to fix this issue we would again need to expose another gradle extension property (say javaHome).

    e) There is a critical error that pops up when we try to use ForkJavaTask from com.github.johnrengelman.processes plugin due to deprecated and removed gradle api

What is the replacement for com.github.johnrengelman.processes plugin

The replacement plugin that I am planning to use is called com.github.hesch.execfork

How will the Spring docs open api gradle plugin work?

Once we add the replacement plugin, the following steps describe how the plugin would work

  1. When spring docs open api gradle plugin is added to the gradle build it adds the following tasks

    a) forkedSpringBootRun is of type com.github.psxpaul.task.JavaExecFork

    b) generateOpenApiDocs

  2. When the user calls the task gradle clean generateOpenApiDocs. The plugin make a call to forkedSpringBootRun task.

  3. forkedSpringBootRuntask internally <b>copies all the task property values of the</b>bootRun` task (added by the spring boot gradle plugin) and runs it in a separate process. Please note at this stage no jar is build.

  4. Finally generateOpenApiDocs makes a call to the spring boot apiDocs url which was started by forkedSpringBootRun task to generate the openapi.json or (.yaml) file and then at end shutdowns the forkedSpringBootRun process.

Important

The main point is the users shouldn't see much difference in running the task.

Any configuration that user needs to provide like setting the environment variable, jvm argument, java home ect, the user can provide those by customization of bootRun task. We the springdoc openapi gradle plugin will automatically copy those values from the bootRun task and use it in our forkedBootRunTask. This way we dont have to provide any customization properties. This means we can drop the forkedProperties extension

One more advantage is forkedBootRunTask now doesnt invoke the jar building process. This mean user can generate the openapi.json file and now added to the jar file quite easily without having to duplicate the jar creation process.

@kpramesh2212
Copy link
Contributor Author

kpramesh2212 commented Dec 3, 2020

@bnasslahsen

Can you please have read through this issue. If all our team is happy with this proposal I can provide an implementation.

This could also help us solve many problem tickets in our queue.

@kpramesh2212
Copy link
Contributor Author

@zendern @dcp65

FYI

What do you guys think of this proposal?

@zendern
Copy link
Contributor

zendern commented Dec 3, 2020

@kpramesh2212 the proposal sounds good to me overall. I think the removal of the forkedProperties and reliance on the bootRun definition might be problematic but I could be an edge case.

So my application has n number of different profiles for different configurations. When running locally we set those accordingly but have the default set to what we use most of the time.

But with this change I would now be setting my default to also have all the things i want configured for springdocs to generate rest docs which are not what I really want in combination with the other profiles. Long story short some endpoints are bound to profiles and during the docs gen i want all the things enabled. But in other cases I do not want that to be the case when doing development.

It's possibly a simple thing that we can probably get over but being able to configure the openApi task definition like we do with forkedProperties makes keeping the separation of concerns that we have nice and easy and straightforward.

Maybe a possible solution to keep it around is this. From what i can tell the new gradle plugin should be able to support that feature via these properties

https://github.com/psxpaul/gradle-execfork-plugin#javaexecfork

image


With that being said if it is deemed to drop that property altogether though probably should make this a major release version. And once that decision is made do a PR that start logging out that the forkedProperties will be going away in the next major version.

@kpramesh2212
Copy link
Contributor Author

@zendern

Both bootRun task provided by SpringBoot and javaexecFork by https://github.com/psxpaul/gradle-execfork-plugin#javaexecfork

are javaExec tasks

Basically if you configure your bootRun with required environment and jvmArgs will it solve our problem

val bootRun by tasks.existing(org.springframework.boot.gradle.tasks.run.BootRun::class) {
    environment = mapOf("MY_Home" to "sweet_home")
    jvmArgs = listOf("jvmArgs")
}

So what we will do is use the forkedBootRun task to call the spring boots bootRun task in the background thats it. Any configuration you want to make you can make it via the bootRun task as shown above.

But if we still require that option forkedProperties we can accommodate it. Have a think about it. I will send you a working version and you could have go and see if it will solve our problems.

@bnasslahsen
Copy link
Contributor

Hi @kpramesh2212,

We can consider that the usage of com.github.johnrengelman.processes plugin has shown the limitations mentioned above, for our usage.
I totally agree with your proposal.

@terziele
Copy link

BTW, why does this plugin has to run a boot application to download its API? Why is documentation generation not static?

@ghost
Copy link

ghost commented Feb 14, 2021

BTW, why does this plugin has to run a boot application to download its API? Why is documentation generation not static?

I've been wondering this myself. The only way I can get the generateOpenApiDocs task to work is to run the Spring Boot application first. That's the way it's supposed to work, right?

@terziele
Copy link

Well, yeah. But still, it seems kinda wild to run a whole application, with a database connection and many other things just to download its REST API. I know you can provide a special configuration, pass some arguments like -Dspring.profiles.active etc. Seems like a very bad user experience, isn't it?
Well, I think I have some other way to do it without running a whole application. But for now, it's a very raw solution, I think. But I can contribute it if the maintainers want to.

@sgrimm
Copy link
Contributor

sgrimm commented Feb 15, 2021

This GitHub issue seems like the wrong place to discuss whether the plugin's core architectural design should be thrown away.

But to answer the question: The schema can't be determined at compile time in the general case because there are APIs to construct and modify it programmatically. For example, in my application, I populate the values of some enumerated string fields in the schema by querying a reference table. You can't express that statically; you have to run the code and the code has to talk to a database. Or for another example, even if you're purely annotation-based, you can declare conditional beans that are present in some configurations but not others, and at compile time there'd be no way to know what combination of them should appear in the generated documents.

@bnasslahsen
Copy link
Contributor

I am closing this issue as i see there is not a lot of activity.
We had a great proposal from @kpramesh2212 to get rid of com.github.johnrengelman.processes plugin.
It's not a blocking one.
But, It's all time better to propose a cleaner solution to the community.

Any PR about it will be welcome!

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

No branches or pull requests

5 participants