groovy
  1. groovy
  2. GROOVY-2503 MOP 2.0 design inflluencing issues
  3. GROOVY-2500

Assignment calls the wrong setter, depending on order of declaration

    Details

    • Type: Sub-task Sub-task
    • Status: Resolved Resolved
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 1.5.1
    • Fix Version/s: 2.4.0-beta-4
    • Component/s: groovy-runtime
    • Labels:
      None
    • Environment:
      Windows XP, java 6 update 4, ant 1.7, groovy 1.6 beta 1
    • Number of attachments :
      0

      Description

      The following build.xml fails:

      <?xml version="1.0" encoding="UTF-8"?>
      <project name="test" default="run">
      
      	<path id="groovy.classpath">
      		<fileset dir="." includes="groovy-*.jar"/>
      	</path>
      
      	<taskdef name="groovy" classname="org.codehaus.groovy.ant.Groovy" classpathref="groovy.classpath"/>
      
      	<target name="compile">
      		<echo file="Test.java">
      			public class Test
      			{
      				public void setField( String value )
      				{ 
      					System.out.println( "String" );
      				}
      			
      				public void setField( Integer value )
      				{ 
      					System.out.println( "Integer" );
      				}
      			}
      		</echo>
      		<javac srcdir="." includes="Test.java"/>
      	</target>
      
      	<target name="run" depends="compile">
      		<groovy>
      			try
      			{
      				new Test().setField( "sss" ) // This works
      				println "success 1"
      				new Test().field = "sss" // This gives exception
      				println "success 2"
      			}
      			catch( Exception e )
      			{
      				e.printStackTrace( System.out )
      			}
      		</groovy>
      	</target>
      
      </project>
      

      (you need to put the groovy.jar in the same folder)

      The setField() succeeds, but the assignment fails.

      If I change the order of the two setField() methods, both succeed.

        Issue Links

          Activity

          Hide
          René de Bloois added a comment -

          Sorry, by accident I did select the 'fix version' instead of the 'affects version'.

          Show
          René de Bloois added a comment - Sorry, by accident I did select the 'fix version' instead of the 'affects version'.
          Hide
          Danno Ferrin added a comment -

          I'll let Jochen or one of the other code compiler committers make the final call, but my vote is to close as "won't fix".

          The real problem comes in with the JavaBeans spec. It only has a defined and reliable behavior (in the absense of BeanInfos) when there is only one set<foo> method for a property. The property shortcut is a function of JavaBeans, so any violation of JavaBeans should also result in a failure for Groovy.

          Show
          Danno Ferrin added a comment - I'll let Jochen or one of the other code compiler committers make the final call, but my vote is to close as "won't fix". The real problem comes in with the JavaBeans spec. It only has a defined and reliable behavior (in the absense of BeanInfos) when there is only one set<foo> method for a property. The property shortcut is a function of JavaBeans, so any violation of JavaBeans should also result in a failure for Groovy.
          Hide
          René de Bloois added a comment -

          If that's the case that would be unfortunate.

          Personally, in groovy I would expect the setter to be equivalent to an assignment, because of the operator overloading that Groovy has. A setter seems to be nothing more than an overloaded field assignment. But that is my first impression. I don't know if this would give any conceptual problems besides the existing technical problems.

          With all the reflection going on in the groovy runtime, isn't it already possible to do it like that?

          And if it is not possible, than I think that this issue should be transformed to "unpredictable behaviour when doing assignment with overloaded setters". I think it should always fail, independent of the declaration order of the setters. (it took me 2 or 3 hours to figure this problem out, developers should be protected against this).

          Show
          René de Bloois added a comment - If that's the case that would be unfortunate. Personally, in groovy I would expect the setter to be equivalent to an assignment, because of the operator overloading that Groovy has. A setter seems to be nothing more than an overloaded field assignment. But that is my first impression. I don't know if this would give any conceptual problems besides the existing technical problems. With all the reflection going on in the groovy runtime, isn't it already possible to do it like that? And if it is not possible, than I think that this issue should be transformed to "unpredictable behaviour when doing assignment with overloaded setters". I think it should always fail, independent of the declaration order of the setters. (it took me 2 or 3 hours to figure this problem out, developers should be protected against this).
          Hide
          blackdrag blackdrag added a comment -

          I changed the fix version and affect version and the priority. It is not a critical bug, because the foo.bar shortcut is thought for beans or something that looks at last partially like a bean, but a overloaded setter is not part of the bean specification. So basically Groovy is not doing anything wrong. As I see it the currentty MOP does not give that functionality away that you would need. we could for example invoke the method by the MetaClass... that would be a small change internally, but the effects might be very big on the outside. And it opens new problem, like for example if missingMethod should be invoked or not... something we decided against for normal properties. But especially in a MetaClass like EMC it might have side effects, that we can't yet foresee.. so I would like to make this part of the 2.0 MOP

          Show
          blackdrag blackdrag added a comment - I changed the fix version and affect version and the priority. It is not a critical bug, because the foo.bar shortcut is thought for beans or something that looks at last partially like a bean, but a overloaded setter is not part of the bean specification. So basically Groovy is not doing anything wrong. As I see it the currentty MOP does not give that functionality away that you would need. we could for example invoke the method by the MetaClass... that would be a small change internally, but the effects might be very big on the outside. And it opens new problem, like for example if missingMethod should be invoked or not... something we decided against for normal properties. But especially in a MetaClass like EMC it might have side effects, that we can't yet foresee.. so I would like to make this part of the 2.0 MOP

            People

            • Assignee:
              Cdric Champeau
              Reporter:
              René de Bloois
            • Votes:
              2 Vote for this issue
              Watchers:
              2 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: