groovy
  1. groovy
  2. GROOVY-4979

@ToString creates additional unneeded field

    Details

    • Number of attachments :
      0

      Description

      Using @ToString(includeNames = true) inserts a field called $print$names into the class. This field is neither transient nor static, which causes havoc when using XStream.

      Example XStream output:

      [
        {
          "name": "み +()[]{}.mp3",
          "size": 690037,
          "outputSize": 0,
          "format": {
            "codec": "mp3",
            "name": "mp3",
            "bitDepth": "s16le",
            "samplingRate": 44100,
            "channels": 2,
            "$print$names": true
          }
        }
      ]
      

      I don't understand why the field is there in the first place since printNames is a compile-time thing.

        Activity

        Hide
        Paul King added a comment -

        The reason for its existence is for legacy behavior of @Immutable which calls through to @ToString. With @Immutable classes created using the named params constructor automatically print out with printNames true whereas ones created with a tuple constructor don't. Current thinking is that we may deprecate this behavior as we have had no feedback indicating that it is absolutely essential for some particular use case and it does add complexity.

        The field is marked "synthetic" and that is enough for some tools to ignore it - for XStream you would have to add an XStream annotation to ignore it or write your own convertor. CGLibConverter for example ignores synthetic fields I believe. This would be the workaround.

        You mention "causes havoc". What exactly do you observe?

        Show
        Paul King added a comment - The reason for its existence is for legacy behavior of @Immutable which calls through to @ToString . With @Immutable classes created using the named params constructor automatically print out with printNames true whereas ones created with a tuple constructor don't. Current thinking is that we may deprecate this behavior as we have had no feedback indicating that it is absolutely essential for some particular use case and it does add complexity. The field is marked "synthetic" and that is enough for some tools to ignore it - for XStream you would have to add an XStream annotation to ignore it or write your own convertor. CGLibConverter for example ignores synthetic fields I believe. This would be the workaround. You mention "causes havoc". What exactly do you observe?
        Hide
        Johann Burkard added a comment -

        How can I add an XStream annotation to a field generated during compiling? Or do you mean something like private transient boolean $print$names = true would work?

        I agree, maybe havoc was the wrong word.

        Show
        Johann Burkard added a comment - How can I add an XStream annotation to a field generated during compiling? Or do you mean something like private transient boolean $print$names = true would work? I agree, maybe havoc was the wrong word.
        Hide
        Paul King added a comment -

        I was hoping XStreamOmitField could be placed on a class with a list of fields to omit but it isn't designed that way at all after checking.

        Show
        Paul King added a comment - I was hoping XStreamOmitField could be placed on a class with a list of fields to omit but it isn't designed that way at all after checking.
        Hide
        Roshan Dawrani added a comment -

        Got interested in how to solve this problem, and documented a technique here as it could be useful to others as well: http://roshandawrani.wordpress.com/2011/09/13/better-serialization-of-groovy-objects-using-xstream/

        Show
        Roshan Dawrani added a comment - Got interested in how to solve this problem, and documented a technique here as it could be useful to others as well: http://roshandawrani.wordpress.com/2011/09/13/better-serialization-of-groovy-objects-using-xstream/
        Hide
        blackdrag blackdrag added a comment -

        What should we do about this issue then?

        Show
        blackdrag blackdrag added a comment - What should we do about this issue then?
        Hide
        Roshan Dawrani added a comment -

        I thought Paul's comment clarified that all Groovy can do is mark its internal fields "synthetic" and then let the libraries utilize that meta-data to ignore them (like CGLibConverter does). And now we have provided a XStream specific workaround as well.

        Let's still wait for a little while for Johann to share his views about it.

        Show
        Roshan Dawrani added a comment - I thought Paul's comment clarified that all Groovy can do is mark its internal fields "synthetic" and then let the libraries utilize that meta-data to ignore them (like CGLibConverter does). And now we have provided a XStream specific workaround as well. Let's still wait for a little while for Johann to share his views about it.
        Hide
        Paul King added a comment -

        Yes, with Roshan's published workaround I would recommend closing the issue if Johann agrees. We might as a separate activity want to deprecate the use of '$print$names' but that is a separate issue.

        Show
        Paul King added a comment - Yes, with Roshan's published workaround I would recommend closing the issue if Johann agrees. We might as a separate activity want to deprecate the use of '$print$names' but that is a separate issue.
        Hide
        Johann Burkard added a comment -

        The issue I think about here is that of annotations creating non-static fields. People can say "Groovy is slow" and that's one (largely irrelevant) thing but if they say "Groovy is slow and its memory usage is completely unpredictable and therefore, it cannot scale," that's unacceptable.

        In other words, if I didn't know it, I wouldn't expect Groovy to add fields to my classes. The fields it adds today are thankfully static so it's not really an issue but per-instance fields might be.

        Show
        Johann Burkard added a comment - The issue I think about here is that of annotations creating non-static fields. People can say "Groovy is slow" and that's one (largely irrelevant) thing but if they say "Groovy is slow and its memory usage is completely unpredictable and therefore, it cannot scale," that's unacceptable. In other words, if I didn't know it, I wouldn't expect Groovy to add fields to my classes. The fields it adds today are thankfully static so it's not really an issue but per-instance fields might be.
        Hide
        Paul King added a comment -

        I'm going to go ahead and close this issue. The internal $print$names field has been removed from Groovy 2.0 in any case. In general, annotations don't add fields (static or otherwise) without careful consideration. It would only be because such a field was required for the functionality of the annotation.

        Show
        Paul King added a comment - I'm going to go ahead and close this issue. The internal $print$names field has been removed from Groovy 2.0 in any case. In general, annotations don't add fields (static or otherwise) without careful consideration. It would only be because such a field was required for the functionality of the annotation.
        Paul King made changes -
        Field Original Value New Value
        Status Open [ 1 ] Resolved [ 5 ]
        Assignee Paul King [ paulk ]
        Fix Version/s 2.0-beta-2 [ 18072 ]
        Resolution Fixed [ 1 ]
        Paul King made changes -
        Status Resolved [ 5 ] Closed [ 6 ]
        Hide
        Paul King added a comment -

        I just looked at the code changes I made for this for 2.0-beta-2 and they didn't seem to be committed - I presume I stuffed up the git command at this end. Re-applying shortly and I'll bump the fix version appropriately.

        Show
        Paul King added a comment - I just looked at the code changes I made for this for 2.0-beta-2 and they didn't seem to be committed - I presume I stuffed up the git command at this end. Re-applying shortly and I'll bump the fix version appropriately.
        Paul King made changes -
        Resolution Fixed [ 1 ]
        Status Closed [ 6 ] Reopened [ 4 ]
        Paul King made changes -
        Fix Version/s 2.0-beta-3 [ 18244 ]
        Fix Version/s 2.0-beta-2 [ 18072 ]
        Hide
        Paul King added a comment -

        fixed glitch

        Show
        Paul King added a comment - fixed glitch
        Paul King made changes -
        Status Reopened [ 4 ] Resolved [ 5 ]
        Resolution Fixed [ 1 ]
        Paul King made changes -
        Status Resolved [ 5 ] Closed [ 6 ]

          People

          • Assignee:
            Paul King
            Reporter:
            Johann Burkard
          • Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: