Demo bytecode upgrades in Gradle
Use existing plugins and run against upgrade provider API-compatible properties in Gradle.
Instructions to try the upgrades out:
-
Clean caches manually (this is just for the demo) by running:
$ rm -rf ~/.gradle/caches/jars-9 -
Run
DISABLE_PROPERTY_UPGRADES=true ./gradlew assembleDebugThis should fail with an exception:
FAILURE: Build failed with an exception. * What went wrong: A problem occurred configuring project ':app'. > Failed to notify project evaluation listener. > 'void org.gradle.api.tasks.compile.CompileOptions.setEncoding(java.lang.String)'We are explicitly disabling bytecode upgrades, so the plugins used in the build run unmodified, and are faced with missing methods.
-
Run
./gradlew assembleDebugThis should now succeed as the plugins used in the build are bytecode-upgraded, i.e. method references to the old Gradle APIs are automatically replaced with equivalent code that uses the new APIs.
This is pretty cool. Thanks for trying this out on Now in Android.
Use existing plugins and run against upgrade provider API-compatible properties in Gradle.
I have a few questions if you don't mind:
- How is an API-compatible property defined? As in, how does Gradle know whether a plugin property can be upgraded?
- And if it can be upgraded, how does Gradle know what to update it to?
Hey @dturner, sorry, just noticed your comment.
Use existing plugins and run against upgrade provider API-compatible properties in Gradle.
I have a few questions if you don't mind:
- How is an API-compatible property defined? As in, how does Gradle know whether a plugin property can be upgraded?
It's "Provider API"-compatible, e.g. using properties defined as RegularFileProperty and friends. See https://docs.gradle.org/current/userguide/lazy_configuration.html
- And if it can be upgraded, how does Gradle know what to update it to?
For now, this effort is only about upgrading Gradle's own APIs from JavaBean properties to use lazy properties instead. Essentially, we plan to change stuff like:
public boolean isIncremental() { /* ... */ }
public void setIncremental(boolean incremental) { /* ... */ }
...to:
@UpgradedProperty
public abstract Property<Boolean> getIncremental();
Whatever is going to be marked as @UpgradedProperty will get "the treatment," so if a third-party plugin has some bytecode calling setIncremental(...), Gradle will automatically treat it as if it called getIncremental().set(...) etc.
We plan to do this change in Gradle 9.0. Soon after we'd like to release support for third-party plugins to upgrade their own APIs in a similar manner, perhaps using the same or a similar annotation.
The plan is to do a blog post soonish about these plans.