6

Github Support Java 16 · Issue #13481 · gradle/gradle · GitHub

 3 years ago
source link: https://github.com/gradle/gradle/issues/13481
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Copy link

mikehearn commented on Oct 11, 2020

edited

This problem really needs to be fixed in a more general way than just bumping ASM versions and doing a new Gradle release.

The problem is that Gradle (sometimes via Groovy) really wants to analyse bytecode in various ways at various points, and pukes when it can't. This is very hard to fix directly because bytecode is not forwards compatible, so you can't analyse versions from the future.

There is therefore only one robust solution: javac must be told to emit old bytecode versions. This it can easily do via the -target and -source flags. Currently it doesn't work because Gradle is still living in a world where new Java versions were rare events, so it just blithely assumes that whatever Java version is running it is the version it should pass to -target/-source. It passes -target 16 -source 16 to javac as part of compiling some Java/Groovy together, the Groovy compiler tries to read the bytecode and can't, then the error gets partly swallowed and it's all a big mess.

This behaviour makes no sense. If Gradle must analyse bytecode then it has only one option it it wants to be compatible with the latest JVMs: it has to cap the target release of any non-user controlled javac invocations at whatever version of Java was the latest supported version at the time of release. This would allow it to be run with the JVM versions "from the future" and still be able to build projects.

That would stem the bleeding, but of course what people want is to be able to use new Java features with old Gradles. They could do so as long as the new feature didn't require new bytecode features (i.e. new APIs but usually not new language features). To support all new Java features with old Gradles implies one of two things:

  1. Gradle must be able to optionally sacrifice its features that rely on reading bytecode (some stuff related to incremental builds, I think?)
  2. Old Gradles must be able to upgrade themselves on the fly to new versions of ASM, because ASM is forwards compatible. This includes ASMs that are lurking, shaded inside Groovy or other dependencies.

The latter approach is definitely the most work, but it would kill the problem once and for all.

At any rate, I hope the Gradle team read this message and think about how to avoid this problem cropping up every six months. As Gradle is not always backwards compatible, the current approach is basically increasing the cost of Java upgrades for Gradle users - now a Java upgrade costs $JAVA_BACKCOMPAT_BREAKS + $GRADLE_BACKCOMPAT_BREAKS. Although I'm sure the Gradle team would love it if everyone upgraded Gradle immediately on upgrade, the world is full of old projects that are parked and no longer receiving significant work. Yet users wish to have a single JDK and still build and work on those old codebases, without upgrading that project's Gradle build. So this feature would help a lot of people over the coming years.


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK