We set up a CI with Jenkins and Docker to build our Gradle projects. All projects use the Gradle Wrapper. I noticed that each time a Gradle build is launched in a new Docker container, a gradle-api jar is generated. this slows done the build significantly. Is there a way to avoid generating this jar at each build?
Are you depending on gradleApi() somewhere?
For example by applying the kotlin-dsl plugin?
Because iirc this is what uses that generated jar. So you could for example instead use Gradle plugin development but need to make sure to adapt this if you change Gradle versions.
Or you could use a Docker image where this generated Jar is already produced and present.
Are you depending on gradleApi() somewhere?
For example by applying the kotlin-dsl plugin?
Because iirc this is what uses that generated jar.
I don’t use gradleApi() directly but all my projects use a custom plugin which has been built with the java-gradle-plugin plugin (which adds the gradleApi() dependency if I understand correctly). I understaood it is the recommanded way to do it.
So you could for example instead use Gradle plugin development but need to make sure to adapt this if you change Gradle versions.
Defining a specific version would not generate the API jar anymore? I will do some tests.
All projects do not use the same version of Gradle, it is defined by their Gradle Wrapper settings, so it is not that simple but it is worth some tests.
Or you could use a Docker image where this generated Jar is already produced and present.
Yes, but it means updating the image each time a new Gradle version is published, not very convenient.
We tried to share subparts of the Gradle cache folder between containers to avoid generating the gradle-api jar at each build but always end up having lock issues.
I did tests with a basic Java project, and noticed that this jar is also generated, so it is not specific to our plugin. I also noticed that the jar is only generated when using Kotlin for the build scripts, it is not generated with Groovy. This confirms what you said about the kotlin-dsl plugin (i guess it is automatically applied when using Kotlin for the build scripts).
I am looking for a solution where I can use a Docker image with any version of Gradle, and not have this jar generated at each build. Any hint?
We tried to share subparts of the Gradle cache folder between containers to avoid generating the gradle-api jar at each build but always end up having lock issues.
You have to be very careful what you share and how, not everything is relocatable. Unless of course the build machines are all identical.
You might want to have a look at Understanding dependency resolution.
I also noticed that the jar is only generated when using Kotlin for the build scripts, it is not generated with Groovy.
Probably because Groovy is highly dynamic and duck-typed, while Kotlin needs to be statically compiled.
This confirms what you said about the kotlin-dsl plugin (i guess it is automatically applied when using Kotlin for the build scripts).
Actually not, but related.
I am looking for a solution where I can use a Docker image with any version of Gradle, and not have this jar generated at each build. Any hint?
I don’t think you will have luck without preparing or using a Docker image where those are present, or mapping some volume into the container where the jar is present or similar.
Yay, good news, there is a dead simple solution now.
Upgrade to Gradle 8.5, this generated jar is not generated at Gradle build time and shipped with the distribution, so it is just there now and does not need to be generated.