Uploaded image for project: 'Groovy'
  1. Groovy
  2. GROOVY-5065

Overriding methods on a Java class metaClass doesn't take effect until instance metaClass is changed

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Open
    • Major
    • Resolution: Unresolved
    • 1.7.1, 1.7.4, 1.8.2
    • None
    • groovy-runtime
    • Can be reproduced on a Groovy Console on any of the affected versions, e.g., 1.7.4

    Description

      When using the metaClass of a Java class to override a method, that change doesn't take effect on new instances of that class, until the metaClass on the instance is changed (though the change doesn't need to have any relation to the overriden method):

      String.metaClass.toString = { -> return "meta method" }
      
      def s = new String("original string")
      
      println s.toString()
      s.metaClass.randomChange = {}
      println s.toString()
      

      The expected output would be

      meta method
      meta method
      

      However, the actual output is

      original string
      meta method
      

      It seems that the instance metaClass doesn't recognize the change until it has been changed itself.

      My first intuition was that there is some caching involved and the change to the instance metaClass invalidates the cached metaClass and the overriden method is pulled in afterwards, but fiddling with InvokerHelper.metaRegistry.setMetaClass() didn't change anything either.

      A simple unit test would be

      String.metaClass.toString = { -> return "meta method" }
      def s = new String("original string")
      assert "meta method", s.toString()
      

      Attachments

        Activity

          People

            Unassigned Unassigned
            christian.hang Christian Hang
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

              Created:
              Updated: