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

MissingMethodExceptions in highly concurrent environments

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Closed
    • Critical
    • Resolution: Fixed
    • 1.5.1
    • 1.5.2
    • None
    • None
    • Quad-core Xeon under 64-bit Suse Linux 9 with kernel 2.6.5-7.282-smp. CPU is Intel(R) Xeon(R) CPU X5355 @ 2.66GHz

    Description

      I believe I have uncovered a threading bug with Groovy 1.5.1 which I can reproduce. This bug is consistently reproducible under 1.5.1, however I cannot get it to happen under 1.0. I have also tried the 1.6 trunk builds and the bug happens there as well.

      We recently starting getting groovy.lang.MissingMethodException at various times in our development code. Our code runs 100's of thousands of groovy expressions in a highly concurrent environment. It wasn't happening at the exact same point each time, but it started when we updated our development hardware (much faster and more cores than before). I've managed to reproduce the bug in a simple class (see below), but even in this class the number of failures varies greatly between runs. For every run, I will get some number of exceptions that look like this:

      Exception in thread "Thread-27" groovy.lang.MissingMethodException: No signature of method: Util.between() is applicable for argument types: (null, java.lang.Integer, java.lang.Integer) values:

      {null, 3, 11}
      at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.unwrap(ScriptBytecodeAdapter.java:54)
      at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.invokeMethodN(ScriptBytecodeAdapter.java:169)
      at Script1.run(Script1.groovy:1)
      at RunnableTest.run(RunnableTest.java:17)
      at java.lang.Thread.run(Thread.java:619)

      Although the types in the parameter list will vary.

      I'm pretty sure this indicates a threading issue. While groovy script is run 5 million times, it only will fail a small handful of times. One thing that is interesting is that I can consistently get the exceptions when running under Linux (which is our production environment), but I never get them running under Windows. On both platforms I am using the latest version of Java6.

      Any help would be much appreciated. Thanks again,

      Chuck
      import groovy.lang.Binding;
      import groovy.lang.GroovyShell;
      import groovy.lang.Script;
      
      public class BugTest {
      
          public static void main(String[] args) {
              for (int i = 0; i < 10; i++) {
                  new Thread(new RunnableTest("return util.between(new Short((short)4), new Integer(3), new Integer(11))")).start();
                  new Thread(new RunnableTest("return util.between(new Integer(4), new Integer(3), new Integer(11))")).start();
                  new Thread(new RunnableTest("return util.between(null, new Integer(3), new Integer(11))")).start();
                  new Thread(new RunnableTest("return util.between('1', '3', '11')")).start();
              }
          }
      
          public static class RunnableTest implements Runnable {
              private Script _script;
                 
              public RunnableTest(String expression) {
                  _script = new GroovyShell().parse(expression);
                  Binding b = new Binding();
                  b.setVariable("util", Util.getInstance());
                  _script.setBinding(b);
              }
                 
              public void run() {
                  for (int i = 0; i < 500000; i++)
                      _script.run();
              }
          }
      
          public static class Util {
              private static Util _INSTANCE = new Util();
               
              public static Util getInstance() {
                  return _INSTANCE;
              }
         
              public boolean between(Object value, Object low, Object high) {
                  if (value == null || low == null || high == null)
                      return false;
         
                  if (value instanceof String) {
                      String val = (String)value;
                      return val.compareTo(low.toString()) >= 0 && val.compareTo(high.toString()) <= 0;
                  }
         
                  if (value instanceof Number && low instanceof Number && high instanceof Number) {
                      double val = ((Number)value).doubleValue();
                      double l = ((Number)low).doubleValue();
                      double h = ((Number)high).doubleValue();
         
                      return val >= l && val <= h;
                  }
         
                  return false;
              }
          }
      }


      Here is the output from the last time I ran it:

      Exception in thread "Thread-7" groovy.lang.MissingMethodException: No signature of method: BugTest$Util.between() is applicable for argument types: (null, java.lang.Integer, java.lang.Integer) values: {null, 3, 11}

      at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.unwrap(ScriptBytecodeAdapter.java:54)
      at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.invokeMethodN(ScriptBytecodeAdapter.java:169)
      at Script1.run(Script1.groovy:1)
      at BugTest$RunnableTest.run(BugTest.java:28)
      at java.lang.Thread.run(Thread.java:619)
      Exception in thread "Thread-11" groovy.lang.MissingMethodException: No signature of method: BugTest$Util.between() is applicable for argument types: (null, java.lang.Integer, java.lang.Integer) values:

      {null, 3, 11}
      at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.unwrap(ScriptBytecodeAdapter.java:54)
      at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.invokeMethodN(ScriptBytecodeAdapter.java:169)
      at Script1.run(Script1.groovy:1)
      at BugTest$RunnableTest.run(BugTest.java:28)
      at java.lang.Thread.run(Thread.java:619)
      Exception in thread "Thread-15" groovy.lang.MissingMethodException: No signature of method: BugTest$Util.between() is applicable for argument types: (null, java.lang.Integer, java.lang.Integer) values: {null, 3, 11}

      at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.unwrap(ScriptBytecodeAdapter.java:54)
      at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.invokeMethodN(ScriptBytecodeAdapter.java:169)
      at Script1.run(Script1.groovy:1)
      at BugTest$RunnableTest.run(BugTest.java:28)
      at java.lang.Thread.run(Thread.java:619)
      Exception in thread "Thread-2" groovy.lang.MissingMethodException: No signature of method: BugTest$Util.between() is applicable for argument types: (java.lang.Integer, java.lang.Integer, java.lang.Integer) values:

      {4, 3, 11}
      at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.unwrap(ScriptBytecodeAdapter.java:54)
      at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.invokeMethodN(ScriptBytecodeAdapter.java:169)
      at Script1.run(Script1.groovy:1)
      at BugTest$RunnableTest.run(BugTest.java:28)
      at java.lang.Thread.run(Thread.java:619)
      Exception in thread "Thread-19" groovy.lang.MissingMethodException: No signature of method: BugTest$Util.between() is applicable for argument types: (null, java.lang.Integer, java.lang.Integer) values: {null, 3, 11}
      at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.unwrap(ScriptBytecodeAdapter.java:54)
      at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.invokeMethodN(ScriptBytecodeAdapter.java:169)
      at Script1.run(Script1.groovy:1)
      at BugTest$RunnableTest.run(BugTest.java:28)
      at java.lang.Thread.run(Thread.java:619)
      Exception in thread "Thread-18" groovy.lang.MissingMethodException: No signature of method: BugTest$Util.between() is applicable for argument types: (java.lang.Integer, java.lang.Integer, java.lang.Integer) values: {4, 3, 11}

      at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.unwrap(ScriptBytecodeAdapter.java:54)
      at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.invokeMethodN(ScriptBytecodeAdapter.java:169)
      at Script1.run(Script1.groovy:1)
      at BugTest$RunnableTest.run(BugTest.java:28)
      at java.lang.Thread.run(Thread.java:619)
      Exception in thread "Thread-1" groovy.lang.MissingMethodException: No signature of method: BugTest$Util.between() is applicable for argument types: (java.lang.Short, java.lang.Integer, java.lang.Integer) values:

      {4, 3, 11}

      at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.unwrap(ScriptBytecodeAdapter.java:54)
      at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.invokeMethodN(ScriptBytecodeAdapter.java:169)
      at Script1.run(Script1.groovy:1)
      at BugTest$RunnableTest.run(BugTest.java:28)
      at java.lang.Thread.run(Thread.java:619)
      Exception in thread "Thread-39" groovy.lang.MissingMethodException: No signature of method: BugTest$Util.between() is applicable for argument types: (null, java.lang.Integer, java.lang.Integer) values:

      {null, 3, 11}

      at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.unwrap(ScriptBytecodeAdapter.java:54)
      at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.invokeMethodN(ScriptBytecodeAdapter.java:169)
      at Script1.run(Script1.groovy:1)
      at BugTest$RunnableTest.run(BugTest.java:28)
      at java.lang.Thread.run(Thread.java:619)

      Attachments

        Activity

          People

            blackdrag Jochen Theodorou
            cmay4 Chuck May
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: