groovy
  1. groovy
  2. GROOVY-4919

Categories sometimes not applied

    Details

    • Type: Bug Bug
    • Status: Open Open
    • Priority: Minor Minor
    • Resolution: Unresolved
    • Affects Version/s: 1.8.0
    • Fix Version/s: None
    • Component/s: groovy-jdk
    • Labels:
    • Environment:
      Debian Lenny Linux
    • Number of attachments :
      0

      Description

      Since upgrading http://media.io to Groovy 1.8.0, I very rarely get these exceptions:

      
      groovy.lang.MissingMethodException: No signature of method: java.lang.String.shaHex() is applicable for argument types: () values: []
      Possible solutions: size(), charAt(int), isCase(java.lang.Object), isCase(java.lang.Object), sleep(long), sleep(long, groovy.lang.Closure)
      	at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.unwrap(ScriptBytecodeAdapter.java:55)
      	at org.codehaus.groovy.runtime.callsite.PojoMetaClassSite.call(PojoMetaClassSite.java:46)
      	at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:112)
      	at media.entities.Info$_getCleanName_closure1.doCall(Info.groovy:87)
      

      The code in Info.groovy uses categories together with commons-codec and looks like this:

      @EqualsAndHashCode(excludes = 'size,outputName,outputSize,format,progress,downloaded,tags')
      class Info implements Serializable {
          
          private static final long serialVersionUID = 3L
          
          String name
      ...
          String getCleanName(String extension) {
              use (DigestUtils) { extension ? new StringBuilder(49).append(name.shaHex()).append('.').append(extension) : name.shaHex() }
          }
          
      }
      

      My guess is that this happens less frequently than every 50000 calls so it's hard for me to reproduce.

      Any ideas? Could this be a thread-safety thing?

        Activity

        Hide
        Guillaume Laforge added a comment -

        Even if hard to reproduce, could you still try to make an easily reproducable sample?

        Show
        Guillaume Laforge added a comment - Even if hard to reproduce, could you still try to make an easily reproducable sample?
        Hide
        Johann Burkard added a comment -

        Sure. Try this:

        @Grab('commons-codec:commons-codec:1.5')
        import org.apache.commons.codec.digest.*
        
        println use (DigestUtils) { 'bla'.shaHex() }
        
        @Grab('org.codehaus.gpars:gpars:0.12')
        import groovyx.gpars.GParsPool
        
        
        GParsPool.withPool(10, {
         (1..1000000).each {
          Closure category = { use (DigestUtils) { 'bla'.shaHex() } }
          Closure asyncCategory = category.async()
          asyncCategory()
         }
        })
        

        I tried running it on this little netbook here but it crashed it. Maybe you have some cycles you can donate?

        Looking at the stacktrace now...

        	at org.codehaus.groovy.runtime.callsite.PojoMetaClassSite.call(PojoMetaClassSite.java:46)
        	at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:112)
        	at media.entities.Info$_getCleanName_closure1.doCall(Info.groovy:87)
        

        Why is it a PojoMetaClassSite? Shouldn't using categories change the call site?

        Show
        Johann Burkard added a comment - Sure. Try this: @Grab('commons-codec:commons-codec:1.5') import org.apache.commons.codec.digest.* println use (DigestUtils) { 'bla'.shaHex() } @Grab('org.codehaus.gpars:gpars:0.12') import groovyx.gpars.GParsPool GParsPool.withPool(10, { (1..1000000).each { Closure category = { use (DigestUtils) { 'bla'.shaHex() } } Closure asyncCategory = category.async() asyncCategory() } }) I tried running it on this little netbook here but it crashed it. Maybe you have some cycles you can donate? Looking at the stacktrace now... at org.codehaus.groovy.runtime.callsite.PojoMetaClassSite.call(PojoMetaClassSite.java:46) at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:112) at media.entities.Info$_getCleanName_closure1.doCall(Info.groovy:87) Why is it a PojoMetaClassSite ? Shouldn't using categories change the call site?
        Hide
        Paul King added a comment -

        At 1000000 it was taking way too long. Set it to 10000 and it has ran fine several times so far. From what you know, is every statement inside the loop important? I.e. do you know whether it is just calling the closure which is important or the "use" statement which tends to cause problems.

        Show
        Paul King added a comment - At 1000000 it was taking way too long. Set it to 10000 and it has ran fine several times so far. From what you know, is every statement inside the loop important? I.e. do you know whether it is just calling the closure which is important or the "use" statement which tends to cause problems.
        Hide
        Johann Burkard added a comment -

        I think it's only the use block. As you can see in the code, the use block is the only thing in the getCleanName method.

        Show
        Johann Burkard added a comment - I think it's only the use block. As you can see in the code, the use block is the only thing in the getCleanName method.
        Hide
        Johann Burkard added a comment -

        Another one that might or might not be related to this one:

        groovy.lang.MissingMethodException: No signature of method: static java.util.regex.Pattern.isCase() is applicable for argument types: (java.util.regex.Pattern) values: [(?i)	artist=(.*)]
        Possible solutions: isCase(java.lang.Object), isCase(java.lang.Object), use([Ljava.lang.Object;), asType(java.lang.Class), is(java.lang.Object)
        	at groovy.lang.MetaClassImpl.invokeStaticMissingMethod(MetaClassImpl.java:1354)
        	at groovy.lang.MetaClassImpl.invokeStaticMethod(MetaClassImpl.java:1340)
        	at org.codehaus.groovy.runtime.InvokerHelper.invokeMethod(InvokerHelper.java:767)
        	at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.invokeMethodN(ScriptBytecodeAdapter.java:164)
        	at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.isCase(ScriptBytecodeAdapter.java:667)
        	at media.parser.OutputParser.callClosureIfMatch(OutputParser.groovy:127)
        

        Source code:

            boolean callClosureIfMatch(String line, def prefix, Closure closure, Info info) {
                if (prefix in Pattern) {
                    Matcher m = prefix.matcher(line)
                    if (m.find()) {
                        addFormatAndTagsIfNecessary(info)
                        closure(m)
                        return true
                    }
                }
        

        Just happened for the first time. Never seen this before even though the code in question has probably seen more than 250000 invocations.

        Show
        Johann Burkard added a comment - Another one that might or might not be related to this one: groovy.lang.MissingMethodException: No signature of method: static java.util.regex.Pattern.isCase() is applicable for argument types: (java.util.regex.Pattern) values: [(?i) artist=(.*)] Possible solutions: isCase(java.lang. Object ), isCase(java.lang. Object ), use([Ljava.lang. Object ;), asType(java.lang. Class ), is(java.lang. Object ) at groovy.lang.MetaClassImpl.invokeStaticMissingMethod(MetaClassImpl.java:1354) at groovy.lang.MetaClassImpl.invokeStaticMethod(MetaClassImpl.java:1340) at org.codehaus.groovy.runtime.InvokerHelper.invokeMethod(InvokerHelper.java:767) at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.invokeMethodN(ScriptBytecodeAdapter.java:164) at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.isCase(ScriptBytecodeAdapter.java:667) at media.parser.OutputParser.callClosureIfMatch(OutputParser.groovy:127) Source code: boolean callClosureIfMatch( String line, def prefix, Closure closure, Info info) { if (prefix in Pattern) { Matcher m = prefix.matcher(line) if (m.find()) { addFormatAndTagsIfNecessary(info) closure(m) return true } } Just happened for the first time. Never seen this before even though the code in question has probably seen more than 250000 invocations.

          People

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

            Dates

            • Created:
              Updated: