-
Notifications
You must be signed in to change notification settings - Fork 4.5k
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
Confusion and issues with mixing Groovy/Kotlin versions in Gradle builds #17375
Comments
💡 The plugin development plugin could warn/fail if the plugin's runtime dependencies include modules that are provided by the Gradle runtime. This would help prevent issues at an early phase of plugin development. |
I think this clarifies a lot of what I've been piecing together by myself, so thank you for putting it together! EDIT: I think I managed to untangle my issue and was able to resolve it (see #16345 (comment)).
|
Gradle plugins written in Kotlin are recommended to use gradle embedded kotlin runtine. For more info about this check gradle/gradle#16345 and gradle/gradle#17375. Using embeddedKotlinVersion we automatically set the correct kotlin version for our plugins based on the gradle version we are currently using.
This issue has been automatically marked as stale because it has not had recent activity. Given the limited bandwidth of the team, it will be automatically closed if no further activity occurs. If you're interested in how we try to keep the backlog in a healthy state, please read our blog post on how we refine our backlog. If you feel this is something you could contribute, please have a look at our Contributor Guide. Thank you for your contribution. |
There's friction and confusion in the community of build and plugin authors about how to mix Groovy/Kotlin versions in Gradle builds. This can be seen in the many open issues on several issue tracker about this, see below. This issue describes the current status quo and aims at starting an open discussion about this problem to find acceptable solutions.
Gradle provides a runtime environment for plugins. This runtime environment includes both Groovy and Kotlin runtimes.
The respective embedded versions can be seen in the output of
gradle --version
. Below are the versions reported for a bunch of Gradle versions:Note that Gradle 6.9 embeds Kotlin 1.4 but it is set up to use the Kotlin language level and api version 1.3 to compile build scripts for backwards compatibility reasons. Gradle 7.0 then enables Kotlin language level and api version 1.4.
Gradle plugins (build scripts, local plugins, external plugins) are executed against the Gradle runtime. Any dependency resolution that happens to resolve external plugins sits on top of the Gradle runtime. The consequence of this is that all plugins used in a build must be compatible with the Gradle runtime.
If a plugin wants to use language features of a more recent version of Groovy or Kotlin, or, a library compiled against a more recent version of Groovy or Kotlin, then it can only do so in a context that is isolated from the Gradle runtime. For example it can use the Worker API with classloader or process isolation.
That's basically how the core
groovy
plugin allows one to compile Groovy sources and run Groovy tests with a more recent version of Groovy than the one embedded in the Gradle runtime.The Kotlin plugin didn't comply with this constraint of the Gradle runtime until 1.5.10. Before that it depended on the
kotlin-stdlib
of the target Kotlin version instead of depending on a version that is compatible with the target Gradle version. This is fixed starting with 1.5.10. This should make the situation much simpler going forward. See KT-41142.On top of this constraint there're builds where one can use Groovy or Kotlin to build custom local plugins. This is done using either
buildSrc
or included builds. In such cases, the local plugins must comply with the Gradle runtime, thus those builds must use a Groovy/Kotlin version compatible with the used Gradle version to build those plugins. As explained above, they can use a different Groovy/Kotlin version to build the actual project sources though.Another use case that should be addressed is authoring plugins that target multiple Gradle versions, using different embedded Groovy/Kotlin versions. The simplest course is to use a Groovy/Kotlin version that is compatible with all targeted Gradle versions, most probably the lowest one. Publishing different variants of a plugin might be a way to leverage more recent versions of Groovy/Kotlin for more recent versions of Gradle.
Some causes of the confusion
Here are two known causes for the confusion, not an exhaustive list:
Lack of knowledge of the constraints described above.
This is most probably a lack of clarity in how this is documented.
Information about this is scattered across the Gradle user manual making it hard to learn and grasp.
Error/warning messages in case of conflicts not helpful if not misleading.
Again, if this is the case those messages should be reworked to be more helpful.
Related issues
Related
gradle/gradle
issuesRelated Kotlin issues
The text was updated successfully, but these errors were encountered: