groovy-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Cédric Champeau <>
Subject Re: A reminder about how things are compiled
Date Wed, 27 Dec 2017 12:29:01 GMT
I think the IDE setup can be improved. I didn't take at shot at this yet.

2017-12-27 13:22 GMT+01:00 Jochen Theodorou <>:

> On 27.12.2017 10:04, Cédric Champeau wrote:
> [...]
>> The consequence, however, is that any change to a Java class in Groovy
>> core is going to produce a different compiler.
> This is fine in the IDE, as long as I do not have to bootstrap
> immediately... which I do not have to.
> But I must say the IDEA setup is still annoying as hell. I freshly
> generated the modules and ended up with a project I cannot compile, because
> of the examples. I then switched to build, but ignore errors, which
> resulted in my main (FileSystemCompiler, GroovyMain) classes not being
> found, because they have not been compiled and I did not add the Groovy
> global lib. Then I added the bootstrap and while the main classes now have
> been found, they have been of course from the bootstrap, not the source. I
> will always have to have a really, really, really good look at things to
> see if I am using bootstrap or not. I mean imagine you remove a class and
> then run from the IDE to see if your test still works. And it will, because
> the damn class is still in the bootstrap jar, which of course you did not
> create a new one. I easily lost more than half a day just trying to setup
> things again. Together with the installation and fixing of intellij
> itself... that was no fun day at all and lost time for Groovy development.
> For Gradle, which is aware of inputs/outputs, it means that the compiler
>> has changed, and that it needs to recompile downstream consumers
>> (subprojects) and, of course, re-execute their tests. This is the _correct
>> behavior_. Gradle is right to do so, because the compiler has changed, so
>> the bytecode generated might be different, but also since Groovy provides a
>> runtime, it also needs to re-execute the tests because the runtime has
>> changed.
>> What I explain is also true of the other tasks we use, like groovydoc, or
>> docgenerator.
> that part is perfectly fine.
> Now, let me explain why changing the strategy to use compiler N-1 is not
>> necessarily a good idea for us: as I explained, Groovy also comes with a
>> runtime. Say that in Groovy 3, we decide to get rid of call site caching,
>> to only use invokedynamic. Then it means that the runtime of Groovy 3 will
>> no longer include call site caching. However, the Groovy classes of the
>> compiler would have been compiled with call site caching, so a _consumer_
>> of the compiler would fail, because those classes would no longer be there
>> at runtime!
>> Of course one might say "then you can use the invokedynamic version" of
>> Groovy to compile Groovy 3, which leads to the last bit of complexity of
>> our build.
> What you normally do is compiler with N-1 to get a compiler for N' and
> then use that compiler to get the real N. Very common strategy. Of course
> that means in a build where we would depend on an older release (N-1), we
> not be able to use features in the new version (N') before we have created
> N', which can actually compile the new features. And only then N could be
> compiled using the new features from N'. Using Java is kind of like saying
> we stay with N'. So there are pros and cons to this approach, it surely
> does not make things more easy from the build side. It would make the
> program code more easy and would be better in terms of "eat you own dog
> food".
> what me really prevents from doing something like this is that the static
> compiler has to many fallbacks to dynamic code where I do not want them.
> Some would have noticed that we now have a "testAll" task for each
>> project. This task executes tests with the "indy" version of the compiler.
>> Which means that in practice, we produce 2 versions of the compiler, not
>> just one. This was the main reason for the complexity of the previous
>> build, that I recently got rid of by using a different strategy and
>> leveraging the Gradle build cache. So, instead of using the same outputs
>> for both compilers, they are now separate, and we can run the tests in 2
>> flavors. The consequence is that tests are executed twice (one for `test`,
>> the other for `testWithIndy`), but the outcome is much cleaner.
>> I hope this clarifies things a bit. Now for daily development, you can
>> use:
>> ./gradlew :test : will only execute the call site caching version of
>> tests for the "core" project
>> ./gradlew :testWithIndy : will only execute the indy version of tests for
>> the "core" project
>> ./gradlew :testAll : will execute both flavors of tests (indy and non
>> indy) for the "core" project
>> And of course you can do the same for any subproject:
>> ./gradlew :groovy-xml:test
>> You can also choose precisely which test to execute by adding `--tests
>> *MyTest*` to the command line.
> testAll and testWithIndy I did not realize,thanks.
> bye Jcohen

View raw message