[groovy-user] Bug - GroovyBean Setter Precedence

0 views
Skip to first unread message

tom.x...@jpmchase.com

unread,
Oct 23, 2007, 3:27:32 PM10/23/07
to us...@groovy.codehaus.org

I don't know whether someone else has found this, but I think it's a
bug.  If I run the following code...

    class Test {
        private String foo
        ^^^^^^^

        def setFoo(String foo) {
            assert foo != null
            this.foo = foo
        }
    }

    t = new Test()
    t.setFoo(null)

...and here's the results:

    C:\Dev\groovy_project>groovy .\bin\scratch.groovy
    Caught: java.lang.AssertionError: Expression: (foo != null). Values: foo = null
            at Test.setFoo(scratch.groovy:5)
            at scratch.run(scratch.groovy:11)
            at scratch.main(scratch.groovy)

Ok, that's expected.  Now let's try making foo a public property:

    class Test {
        public String foo
        ^^^^^^

        def setFoo(String foo) {
            assert foo != null
            this.foo = foo
        }
    }

    t = new Test()
    t.setFoo(null)

...and here's the results:

    C:\Dev\groovy_project>groovy .\bin\scratch.groovy
    Caught: java.lang.AssertionError: Expression: (foo != null). Values: foo = null
            at Test.setFoo(scratch.groovy:5)
            at scratch.run(scratch.groovy:11)
            at scratch.main(scratch.groovy)

Ok, that's also expected.  Now let's drop the foo property's modifier,
which should make the property "public" by default:

    class Test {
        String foo

        def setFoo(String foo) {
            assert foo != null
            this.foo = foo
        }
    }

    t = new Test()
    t.setFoo(null)

...and here's the results:

    C:\Dev\groovy_project>groovy .\bin\scratch.groovy
    C:\Dev\groovy_project>_

According to GINA, when a class has a public property and a setter for
that property, the property has precedence.  However, in practice (with
1.0), this doesn't seem to be the case.

Is this a new bug?  If not, then I'll be glad to add it to the system.

Thanks,

Tom Purl


This communication is for informational purposes only. It is not intended as an offer or solicitation for the purchase or sale of any financial instrument or as an official confirmation of any transaction. All market prices, data and other information are not warranted as to completeness or accuracy and are subject to change without notice. Any comments or statements made herein do not necessarily reflect those of JPMorgan Chase & Co., its subsidiaries and affiliates. This transmission may contain information that is privileged, confidential, legally privileged, and/or exempt from disclosure under applicable law. If you are not the intended recipient, you are hereby notified that any disclosure, copying, distribution, or use of the information contained herein (including any reliance thereon) is STRICTLY PROHIBITED. Although this transmission and any attachments are believed to be free of any virus or other defect that might affect any computer system into which it is received and opened, it is the responsibility of the recipient to ensure that it is virus free and no responsibility is accepted by JPMorgan Chase & Co., its subsidiaries and affiliates, as applicable, for any loss or damage arising in any way from its use. If you received this transmission in error, please immediately contact the sender and destroy the material in its entirety, whether in electronic or hard copy format. Thank you. Please refer to http://www.jpmorgan.com/pages/disclosures for disclosures relating to UK legal entities.

Jochen Theodorou

unread,
Oct 23, 2007, 3:44:18 PM10/23/07
to us...@groovy.codehaus.org
tom.x...@jpmchase.com schrieb:
[...]

> class Test {
> String foo
>
> def setFoo(String foo) {
> assert foo != null
> this.foo = foo
> }
> }
>
> t = new Test()
> t.setFoo(null)

this gets you two setFoo methods, one with Object, one with String as
return type. Which one of these is used depends on the method ordering
of your VM... in other words it is random. To confirm this, try and
change the "def" to "String"

it is not exactly a bug, as we for now allow two methods like these...
but maybe it is time to move away from it too.

bye blackdrag

--
Jochen "blackdrag" Theodorou
Groovy Tech Lead (http://groovy.codehaus.org)
http://blackdragsview.blogspot.com/
http://www.g2one.com/

---------------------------------------------------------------------
To unsubscribe from this list please visit:

http://xircles.codehaus.org/manage_email

Tom Purl

unread,
Oct 24, 2007, 11:47:01 AM10/24/07
to us...@groovy.codehaus.org

>tom.x...@jpmchase.com schrieb:
>[...]
>> class Test {
>> String foo
>>
>> def setFoo(String foo) {
>> assert foo != null
>> this.foo = foo
>> }
>> }
>>
>> t = new Test()
>> t.setFoo(null)

>this gets you two setFoo methods, one with Object, one with String as
>return type. Which one of these is used depends on the method ordering
>of your VM... in other words it is random. To confirm this, try and
>change the "def" to "String"

Oh ok, so if I declare a method using `def`, then it automatically
assigns an "Object" return type. So I guess it would make sense that
groovy would also create a setFoo() method with a "void" return type in
this case.

What I don't get is why my script's behavior changes when I change the
`String foo` declaration to `public String foo`. I thought the two
lines were equivalent as far as groovyc was concerned, and would
therefore produce identical class files.

Thanks for the help Jochen!

Tom Purl

--
View this message in context: http://www.nabble.com/Bug---GroovyBean-Setter-Precedence-tf4679840.html#a13384961
Sent from the groovy - user mailing list archive at Nabble.com.

Danno Ferrin

unread,
Oct 24, 2007, 12:11:04 PM10/24/07
to us...@groovy.codehaus.org
What I don't get is why my script's behavior changes when I change the
`String foo` declaration to `public String foo`.  I thought the two
lines were equivalent as far as groovyc was concerned, and would
therefore produce identical class files.

They are not.  "String foo" will create public JavaBeans accessors String getFoo() and setFoo(String) in addition to creating a field foo with (I beleive) package level access.  'public String foo' only creates a public field foo.  There are no 'package access' naked fields in groovy.

Both fields and JavaBeans properties via accessors are accessed via the dot operator, with preference to properties.  This may be the confusing part.

--Danno

Jochen Theodorou

unread,
Oct 24, 2007, 12:19:52 PM10/24/07
to us...@groovy.codehaus.org
Tom Purl schrieb:

>
>> tom.x...@jpmchase.com schrieb:
>> [...]
>>> class Test {
>>> String foo
>>>
>>> def setFoo(String foo) {
>>> assert foo != null
>>> this.foo = foo
>>> }
>>> }
>>>
>>> t = new Test()
>>> t.setFoo(null)
>
>> this gets you two setFoo methods, one with Object, one with String as
>> return type. Which one of these is used depends on the method ordering
>> of your VM... in other words it is random. To confirm this, try and
>> change the "def" to "String"
>
> Oh ok, so if I declare a method using `def`, then it automatically
> assigns an "Object" return type. So I guess it would make sense that
> groovy would also create a setFoo() method with a "void" return type in
> this case.

ups, sorry... of course void, not String for the setter, String would be
for the getter :)

> What I don't get is why my script's behavior changes when I change the
> `String foo` declaration to `public String foo`. I thought the two
> lines were equivalent as far as groovyc was concerned, and would
> therefore produce identical class files.

don't put too much into this. You get a random method... I don't think
there is a real correlation

bye blackdrag

---------------------------------------------------------------------

Jochen Theodorou

unread,
Oct 24, 2007, 12:21:54 PM10/24/07
to us...@groovy.codehaus.org
Danno Ferrin schrieb:

> What I don't get is why my script's behavior changes when I change the
> `String foo` declaration to `public String foo`. I thought the two
> lines were equivalent as far as groovyc was concerned, and would
> therefore produce identical class files.
>
> They are not. "String foo" will create public JavaBeans accessors
> String getFoo() and setFoo(String) in addition to creating a field foo
> with (I beleive) package level access.

the field is private, the accessor methods are public.

> 'public String foo' only creates
> a public field foo. There are no 'package access' naked fields in groovy.

no, a private field, but yes... Oh I misread in the other mail... I
guess I need a pause now ;)

bye blackdrag

---------------------------------------------------------------------

Mark Menard

unread,
Oct 24, 2007, 3:00:05 PM10/24/07
to us...@groovy.codehaus.org
I have been happily developing away for a long time now using Maven and the
groovy-all 1.0 artifact from the maven repositories.

Today, around 4AM a new pom file was uploaded for groovy-all 1.0. This pom
file includes a dependency on OpenEJB, which in turn has a dependency on an
artifact that doesn't seem to be available via the repository:

Error from Maven:

[INFO]
------------------------------------------------------------------------
[ERROR] BUILD ERROR
[INFO]
------------------------------------------------------------------------
[INFO] Failed to resolve artifact.

Missing:
----------
1) castor:castor:jar:0.9.9.0-pre

Try downloading the file manually from the project website.

Then, install it using the command:
mvn install:install-file -DgroupId=castor -DartifactId=castor \
-Dversion=0.9.9.0-pre -Dpackaging=jar -Dfile=/path/to/file

Path to dependency:
1) net.vitarara.quadran:quadran-core:war:1.0-SNAPSHOT
2) groovy:groovy-all:jar:1.0
3) openejb:openejb-loader:jar:1.0
4) openejb:openejb-core:jar:1.0
5) castor:castor:jar:0.9.9.0-pre


Quick questions:

1. Why did the pom file all of the sudden change?

2. Any idea what to do to satisfy this dependency?

3. I thought groovy-all was supposed to obviate the need to load a lot of
dependencies, and extra jar files. Was I wrong?

In the mean time I've reverted my m2 repository and am using it in offline
mode, but that's a bit sub-optimal.

I'd be thankful for any advice,

Mark
--
Mark Menard
personal: http://www.vitarara.org/
business: http://www.vitarara.net/

Paul King

unread,
Oct 24, 2007, 4:24:59 PM10/24/07
to us...@groovy.codehaus.org

Hi Mark, I'll see if I can fix this - might take a few days.

Paul.

Mark Menard

unread,
Oct 24, 2007, 4:50:43 PM10/24/07
to us...@groovy.codehaus.org
On 10/24/07 4:24 PM, "Paul King" <pa...@asert.com.au> wrote:

>
> Hi Mark, I'll see if I can fix this - might take a few days.

Thanks a lot Paul. There is also a note about this on:

http://jira.codehaus.org/browse/MEV-549

Someone else there noted the same issue.

Arnaud HERITIER

unread,
Oct 24, 2007, 5:56:15 PM10/24/07
to us...@groovy.codehaus.org, repos...@maven.org
In theory it is forbidden to modify a pom already deployed on a repository
A pom is an artifact like another (jar, war, ...)
To change it you have to change the version !!
I don't know if there's a check to avoid the upload of an existing artifact on the central repository. it seems that it isn't the case !

Arnaud
--
..........................................................
Arnaud HERITIER
..........................................................
OCTO Technology - aheritier AT octo DOT com
www.octo.com | blog.octo.com
..........................................................
ASF - aheritier AT apache DOT org
www.apache.org | maven.apache.org
...........................................................
Reply all
Reply to author
Forward
0 new messages