When I generate the binary tasks, I want to pass the BinarySpec property to the task, but Gradle says the args element is not mutable. Here is the relevant code:
Yes, you can use a BinarySpec as input, but since Gradle is trying to ensure immutability for managed inputs, anything you do that could potentially modify the input will be blocked. In this case, I believe that since you’re able to modify the list returned by getArgs(), it’s considered illegal. You’ll have to make a copy of the list, or iterate and copy the elements, to avoid the error. That said, Java is not my main language, so I may be overlooking some other aspect of it here.
I fail to see how I can copy the args. According to the @Managed documentation, when I use Java 8, I should be able to use an interface default method and return a copy of the args:
Looks like you’re beyond what I’ve figured out so far.
I didn’t have the list copy problem directly myself, but was using aManagedSet.withType(SomeType) { /* closure */ } which adds the closure to the collection for future adds, triggering the error. The solution was to instead iterate over the collection directly, as it’s supposed to be completely resolved anyway.
Would give me the not mutable exception (Cannot set value for model element ‘components.juiceComponent.binaries.juicer.args’ as this element is not mutable.).
But after I changed the creation rule to a mutation rule in the DSL like so:
model {
components {
juiceComponent(JuiceComponent) {
binaries {
juicer { // This is now a mutation rule
args = ['a', 'b']
}
}
}
}
}
Then the exception went away. So now I wonder, how do I assign values to task inputs when a creation rule is used?
It took me a while to discover that the @BinaryTasks generateTask(...) method was being called TWICE. It is called a FIRST time for the binary defined internally: