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

Documentation error for ExpandoMetaClass

    XMLWordPrintableJSON

Details

    Description

      The following javadoc has a warning that was true under Grails from way back but I don't believe applies anymore when this functionality was ported to Groovy 1.1:

      http://groovy.codehaus.org/api/groovy/lang/ExpandoMetaClass.html

      WARNING: This MetaClass uses a thread-bound ThreadLocal instance to store and retrieve properties. In addition properties stored use soft references so they are both bound by the life of the Thread and by the soft references. The implication here is you should NEVER use dynamic properties if you want their values to stick around for long periods because as soon as the JVM is running low on memory or the thread dies they will be garbage collected.

      It is also mentioned here:

      http://groovy.codehaus.org/ExpandoMetaClass+-+Properties

      However, using this technique the property is stored in a ThreadLocal, WeakHashMap so don't expect the value to stick around forever!

      My guess is when Expando was ported into Groovy 1.1 the javadocs weren't updated appropriately to reflect the changes as discussed here:

      http://groovy.329449.n5.nabble.com/Adding-properties-failed-with-ExpandoMetaClass-td343953.html

      It was added here:

      http://jira.codehaus.org/browse/GROOVY-1720

      Using ThreadLocale wouldn't be amiable to server side RIA frameworks such as Vaadin where objects live beyond the request/response cycle.

      This test case clearly shows that it isn't bound to a ThreadLocale or this would fail:

      String.metaClass.swapCase = {->
            def sb = new StringBuffer()
            delegate.each {
                 sb << (Character.isUpperCase(it as char) ? Character.toLowerCase(it as char) : 
                         Character.toUpperCase(it as char))
            }
            sb.toString()
      }
      
      
      println 'THIS IS A TEST'.swapCase()
      
      new Thread(new Runnable() {
         
          void run() {
              println 'ANOTHER'.swapCase()
          }
      }).start()
      
      Thread.sleep(1000L)
      
      

      Attachments

        Activity

          People

            paulk Paul King
            krasmussen Kirk Rasmussen
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: