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

using "as" to coerce a String to an Enum value results in a groovy.lang.MissingMethodException under high contention

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Closed
    • Major
    • Resolution: Fixed
    • 1.8.4
    • 1.8.5, 2.0-beta-2, 1.7.11
    • None
    • None
    • OS X lion w/ JDK1.6.0_29 (build 1.6.0_29-b11-402-11M3527)

    Description

      I've provided a test case in the form of a simple script that can be run in GroovyConsole.

      It creates 5000 threads – each thread converts strings to enums in a loop.
      I tried three different methods of converting strings to Enums in the test.

      These two seem to work fine:

      Foo f = Foo.valueOf(key)
      Foo f = Enum.valueOf(Foo, key)

      However, under load, this method:

      Foo f = key as Foo

      will occasionally throw an exception like the following:

      Exception in thread "Thread-127349" 
      org.codehaus.groovy.runtime.InvokerInvocationException: groovy.lang.MissingMethodException: No signature of method: static Foo.valueOf() is applicable for argument types: (java.lang.String) values: [bar]
      Possible solutions: valueOf(java.lang.String), valueOf(java.lang.Class, java.lang.String), values()
      	at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:97)
      	at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:233)
      	at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:272)
      	at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:883)
      	at groovy.lang.Closure.call(Closure.java:410)
      	at groovy.lang.Closure.call(Closure.java:404)
      	at groovy.lang.Closure.run(Closure.java:488)
      	at java.lang.Thread.run(Thread.java:680)
      Caused by: groovy.lang.MissingMethodException: No signature of method: static Foo.valueOf() is applicable for argument types: (java.lang.String) values: [bar]
      Possible solutions: valueOf(java.lang.String), valueOf(java.lang.Class, java.lang.String), values()
      	at groovy.lang.MetaClassImpl.invokeStaticMissingMethod(MetaClassImpl.java:1349)
      	at groovy.lang.MetaClassImpl.invokeStaticMethod(MetaClassImpl.java:1335)
      	at org.codehaus.groovy.runtime.InvokerHelper.invokeMethod(InvokerHelper.java:767)
      	at org.codehaus.groovy.runtime.DefaultGroovyMethods.asType(DefaultGroovyMethods.java:17327)
      	at org.codehaus.groovy.runtime.dgm$58.doMethodInvoke(Unknown Source)
      	at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1053)
      	at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:883)
      	at org.codehaus.groovy.runtime.InvokerHelper.invokePojoMethod(InvokerHelper.java:781)
      	at org.codehaus.groovy.runtime.InvokerHelper.invokeMethod(InvokerHelper.java:772)
      	at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.invokeMethodN(ScriptBytecodeAdapter.java:164)
      	at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.asType(ScriptBytecodeAdapter.java:587)
      	at TestCase$_run_closure1_closure4_closure5.doCall(TestCase.groovy:12)
      	at sun.reflect.GeneratedMethodAccessor682.invoke(Unknown Source)
      	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
      	at java.lang.reflect.Method.invoke(Method.java:597)
      	at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:90)
      	at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:233)
      	at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:272)
      	at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:883)
      	at groovy.lang.Closure.call(Closure.java:410)
      	at groovy.lang.Closure.call(Closure.java:423)
      	at org.codehaus.groovy.runtime.DefaultGroovyMethods.times(DefaultGroovyMethods.java:12140)
      	at org.codehaus.groovy.runtime.dgm$753.invoke(Unknown Source)
      	at org.codehaus.groovy.runtime.callsite.PojoMetaMethodSite$PojoMetaMethodSiteNoUnwrapNoCoerce.invoke(PojoMetaMethodSite.java:271)
      	at org.codehaus.groovy.runtime.callsite.PojoMetaMethodSite.call(PojoMetaMethodSite.java:53)
      	at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:116)
      	at TestCase$_run_closure1_closure4.doCall(TestCase.groovy:10)
      	at sun.reflect.GeneratedMethodAccessor672.invoke(Unknown Source)
      	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
      	at java.lang.reflect.Method.invoke(Method.java:597)
      	at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:90)
      	at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:233)
      	at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:272)
      	at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:883)
      	at org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.callCurrent(PogoMetaClassSite.java:66)
      	at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:141)
      	at TestCase$_run_closure1_closure4.doCall(TestCase.groovy)
      	at sun.reflect.GeneratedMethodAccessor665.invoke(Unknown Source)
      	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
      	at java.lang.reflect.Method.invoke(Method.java:597)
      	at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:90)
      	... 7 more
      

      It's a concurrency issue, so the test isn't 100% reliable, but on my hardware this test can make the "as" conversion fail at least once in a test run most of the time. The other two methods seem to always work.

      Attachments

        1. TestCase.groovy
          0.4 kB
          Sean Reilly

        Activity

          People

            melix Cédric Champeau
            sreilly@equalexperts.com Sean Reilly
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: