Skip to content
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

Gradle 8 compatibility #9

Closed
TheMrMilchmann opened this issue Feb 21, 2023 · 7 comments
Closed

Gradle 8 compatibility #9

TheMrMilchmann opened this issue Feb 21, 2023 · 7 comments
Assignees
Labels
a:feature New feature or request
Milestone

Comments

@TheMrMilchmann
Copy link
Owner

TheMrMilchmann commented Feb 21, 2023

Gradle 8 changed a lot of internals to use the property&provider API more extensively. This has caused the configuration applied by this plugin to break. I'm aware that the configuration could be considered hacky but, unfortunately, I'm not aware of a public API to implement the plugin properly.

Specifically, the plugin currently sets the javaCompiler property of JavaCompile tasks to null to avoid some default configuration. The ECJ is later plugged in using the forkOptions. This works on Gradle 7.x but not on later versions. Adjustments are necessary to fix this.

  • [ ] Reenable CI checks for the samples
@TheMrMilchmann TheMrMilchmann added the a:feature New feature or request label Feb 21, 2023
@TheMrMilchmann TheMrMilchmann added this to the 0.2.0 milestone Feb 21, 2023
@TheMrMilchmann TheMrMilchmann self-assigned this Feb 21, 2023
@TheMrMilchmann
Copy link
Owner Author

I was pointed at https://docs.gradle.org/current/userguide/upgrading_version_7.html#toolchain_based_tasks_for_jvm_projects by someone.

Starting with Gradle 8.0, all core Java tasks that have toolchain support are now using toolchains unconditionally. If JavaBasePlugin is applied, the convention value for tool properties on the task is defined by the toolchain configured on the java extension. In case no toolchains are explicitly configured, the toolchain corresponding to the JVM running Gradle is used.
Similarly, tasks from the Groovy and Scala plugins also rely on toolchains to determine on which JVM they are executed.

It seems as if there is simply no supported way to accomplish this anymore at the moment. (See gradle/gradle#14768 and gradle/gradle#22400)

@TheMrMilchmann TheMrMilchmann pinned this issue Feb 21, 2023
@TheMrMilchmann
Copy link
Owner Author

See also gradle/gradle#15942 (comment)

@TheMrMilchmann
Copy link
Owner Author

Alright. I filed gradle/gradle#23990 since this seems to be a regression. Can't do anything else here for now.

@liblit
Copy link

liblit commented Feb 21, 2023

The WALA project compiles all code twice: once using standard JavaCompile tasks and again using an ECJ-based JavaCompile task variant that we call JavaCompileUsingEcj. Each new Gradle release breaks the latter in some new way, and we figure out how to fix it again. If it would be helpful to you to see how we did it for Gradle 8.0, you can find the main implementation here.

@TheMrMilchmann
Copy link
Owner Author

Hi @liblit,
the goal of this plugin is to provide ECJ as a drop-in replacement for javac. Compiling the project twice would add a significant overhead that I'd like to avoid. Additionally, this is used in various (non-public) projects for which javac fails due to long-standing bugs related to generics or where it performs extremely poorly. (We're talking about a factor 10 performance difference here.) In both cases, compiling the project using both compilers would not work. Thus, unfortunately, your solution does not help here.

@liblit
Copy link

liblit commented Feb 23, 2023

WALA's strategy to compile everything twice is intentional. We like getting two compilers' opinions on our code. Certainly, the big overhead of doing that isn't for everyone.

WALA's approach requires that I create new compilation instances using a new JavaCompile subclass with a different @TaskAction method. That's not something one can emulate merely by reconfiguring existing standard JavaCompile tasks. So no, @TheMrMilchmann, my approach does not solve your exact problem. I never said that it did.

I merely thought that people looking at this issue might benefit from seeing how a related (but different) problem was solved, and maybe get some new ideas of their own. For example, perhaps someone can figure out how to configure other tasks (e.g., jar) to use bytecode produced by a new set of WALA-like ECJ-based compile tasks instead of the standard compile tasks. I have no idea if that's possible or not. But it's an option that someone might choose to explore, barring simpler alternatives from you or better support from Gradle.

TheMrMilchmann added a commit that referenced this issue Mar 2, 2023
This is incomplete and does not fully work yet. We might have to get rid of the lazy configuration of `forkOptions.executable`. See gradle/gradle#23990 (comment)

See #9
@TheMrMilchmann
Copy link
Owner Author

I have implemented support for (what will probably be) Gradle 8.0.2 based on the fix for the reported issue and this suggestion. The approach taken for 7.x and 8.x is now slightly different and using the plugin for 8.x will now provide a better experience:

  1. The javaCompiler property of JavaCompile tasks is now respected and used to derive the JVM to run the compiler.
  2. Up-to-date checks should behave more reliably on Gradle 8.

@TheMrMilchmann TheMrMilchmann unpinned this issue Mar 3, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
a:feature New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants