Hi. I have the following build file:
task a {
onlyIf = {
println ‘only if b’; true
} }
where I want to use setOnlyIf. As in Groovy, I use the property setter syntax. Gradle can only partly cope with it - it calls a sette, but a wrong one:
- What went wrong: A problem occurred evaluating root project ‘test_gradle’. > Cannot cast object ‘build_3qjq2ih65t4sj9l3mk4n6d6p2u$_run_closure2_closure8@27a7cac9’ with class ‘build_3qjq2ih65t4sj9l3mk4n6d6p2u$_run_closure2_closure8’ to class ‘org.gradle.api.specs.Spec’
It looks as though the call is delegated to a wrong method. Is this normal?
System: rafal@studio:~/Playground/test_gradle$ gradle -version
------------------------------------------------------------ Gradle 1.0-rc-1 ------------------------------------------------------------
Gradle build time: Wednesday, April 11, 2012 11:13:24 AM UTC Groovy: 1.8.6 Ant: Apache Ant™ version 1.8.2 compiled on December 20 2010 Ivy: 2.2.0 JVM: 1.7.0_03 (Oracle Corporation 22.1-b02) OS: Linux 3.0.0-12-generic amd64
In this particular case, the setter is overloaded too (probably not a good idea). I don’t think Groovy will handle this in the ‘expected’ way. In order to use a closure, you should use the ‘onlyIf’ method: ‘onlyIf { … }’.
Hi Peter. I don’t want / can’t to use onlyIf as it is different - it appends a condition, whereas setOnlyIf kind of removes all previous ones and uses the one it was called with.
Anyways, you are very right, it seems to be Groovy’s problem with overloaded setters:
class T {
void setOnlyIf(Closure c) { println ‘closure’ }
void setOnlyIf(String s) { println ‘s’ } }
new T().onlyIf = { ‘some code’ } // works, probably by accident - the first setter new T().onlyIf = ‘a’ // explodes, wants to call the closure version
In that case, I think I will ask at the Groovy mailing list.
wujek
It just ocurred to me, I can always write:
new T().setOnlyIf { ‘some code’ } new T().setOnlyIf ‘a’
(i.e., no equals sign) which is still Groovy ;d
You can, but there is no good reason not to use the ‘onlyIf’ method instead. It’s a common pattern in Gradle to have a property along with some convenience methods that accept additional representations.
Yes, but as I said, they are different, right? This behaves differently:
task … {
onlyIf { … }
onlyIf { … } }
task … {
onlyIf { … }
setOnlyIf { … } }
In the latter’s case, setOnlyIf makes the previous onlyIfs disappear (at least the docs say so), which is exactly what I want to test.
Yes, they are different. I didn’t know that you are trying to override a previous ‘onlyIf’. As for the Groovy property behavior, I think it works as designed. Overloaded setters don’t conform to the JavaBeans specification.