We have a huge number of Gradle modules and many Jar tasks mostly creating “fat JARs”. This is causing the configuration phase to take quite a lot of time.
So a colleague of mine came up with an “optimization” to move the from() and manifest() method calls into doFirst() method:
the manifest content is not taken into account for incremental builds
the changes/additions/removals of any from() method call are not taken into account for incremental builds
if the task would be part of the default jar definition, then some files will be part of incremental build (class files from main sourceSet) but any custom files not, causing hidden consistency mismatch
Generally speaking allowing methods part of incremental build to be called in execution phase might cause many issues and should be rejected.
I was wondering if such behavior could be rejected by throwing an exception during execution phase.
the above code should already fail with Gradle 4.0. You can try out Gradle 4.0 M2 and give it a spin. We already print a deprecation message in the Gradle 3.x series.
I think you should be able to have both - fast configuration time and correct incremental build.
The easiest solution for your problem would be to add a different task which configures copyStuff - a so called configure task. So you would end up with something like
The calls to from() are OK and correct. They’re lazily evaluated already, so putting these into doFirst is unnecessary and could lead to problems. I think we should try to prevent that.
In this particular case, what we’re missing is an easy way to lazily evaluate manifest attributes. We call toString on any attribute value, so we should be able to fake it. I haven’t tried this, but something like this may work:
I had the same problem with lazy evaluation of classpath for manifest attributes. I found this solution and after further search, it think it should be possible to use lazy string evaluation like this (lazy expressions):