feat: keep published artifacts on invokedynamic, let applications choose - #16171
Open
codeconsole wants to merge 1 commit into
Open
feat: keep published artifacts on invokedynamic, let applications choose#16171codeconsole wants to merge 1 commit into
codeconsole wants to merge 1 commit into
Conversation
Callsite caching links call sites at runtime and cannot be compiled ahead of time, so a native image needs every class on the classpath to be the invokedynamic flavour. One dependency compiled the other way rules out a native image for every application that uses it. A project applying the grails-plugin plugin therefore always compiles its published classes with invokedynamic and ignores grails.indy, so a plugin build can no longer strip native compatibility from its consumers. Plugin authors need to change nothing; a plugin build that sets indy can drop it. grails.indy still applies to applications, which sit at the end of the classpath and may choose for their own sources, and now defaults to true following Groovy's own default rather than false. An application setting it to false opts itself out of native compilation but still runs correctly against the invokedynamic artifacts of the framework and its plugins. The -PgrailsIndy toggle used by CI now applies only to the application-type projects in this repository.
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## 8.0.x #16171 +/- ##
==================================================
- Coverage 52.3364% 52.3204% -0.0160%
+ Complexity 18545 18519 -26
==================================================
Files 2039 2039
Lines 97521 97524 +3
Branches 17143 17159 +16
==================================================
- Hits 51039 51025 -14
- Misses 38994 39034 +40
+ Partials 7488 7465 -23
🚀 New features to boost your workflow:
|
✅ All tests passed ✅🏷️ Commit: 2c9410c Learn more about TestLens at testlens.app. |
Contributor
|
I would 100% support using a classifier to let end users chose. I do not support having indy be the default for Groovy 5 though. The performance isn't there yet and it's enough that we already decided to remove it. I'm a -1 on making it the default until we can get the performance to be on par (which I think Groovy 6 does) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Alternative to #16170. Same problem, opposite conclusion: instead of publishing every artifact twice, publish each one once — always as
invokedynamic.Why
Call-site caching links call sites at runtime, which ahead-of-time native compilation cannot do. A native image needs every class on the classpath to be the
invokedynamicflavour, so one dependency compiled the other way rules out a native image for every application that depends on it.That makes the flavour of a published artifact not really its own build's decision. Today a plugin author can set
grails { indy = false }and silently strip native compatibility from every application using that plugin.What changes
A project applying
org.apache.grails.gradle.grails-pluginalways compiles its published classes withinvokedynamicand ignoresgrails.indy. Plugin authors need to change nothing; a plugin build that setsindycan drop it.grails.indystill applies to applications, which sit at the end of the classpath and may choose for their own sources. It now defaults totrue, following Groovy's own default, rather thanfalse. An application setting it tofalseopts itself out of native compilation but still runs correctly against theinvokedynamicartifacts of the framework and its plugins — the two flavours interoperate on the same classpath.This also resolves an existing incoherence: the framework currently ships mixed bytecode (
grails-controllersindy-on,grails-gspindy-off) purely from which modules happened to adoptgrails-plugin. Every published artifact is nowinvokedynamic.Compared to #16170
The
noindyartifacts that #16170 publishes can never be used in a native build, so they double the release surface to serve only the non-native case — which this PR still supports for an application's own code at no artifact cost.Verification
4 functional tests in
GrailsIndyAppOnlySpec: a plugin that explicitly setsindy = falsestill emitsPLUGIN_BYTECODE=indy=true,callsite=false; no second-flavour tasks exist; an application can still choose call-site caching for itself; an application configuring nothing follows Groovy's default.On a real module:
grails-cacheappliesgrails-pluginand compiled with zeroinvokedynamicinstructions on8.0.x. On this branch, 17 of its 37 classes carry them.Suite: 96/99 passing. The 3
GroovyPageToolchainSpecfailures are environmental — they need a JDK 21 toolchain that is not installed on the machine I ran them on, and they fail identically on unmodified8.0.x.codeStyleclean.Reviewer notes
./gradlew buildhas not been run; one framework module was built and inspected locally.grails-pluginchange from indy-off to indy-on, which is the intended unification but is the change most likely to show in a performance comparison against 7.x.