onlyIf = {...} results in build error

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.