Friday, October 12, 2007

Groovy Class Extension Gotcha

I've recently upgraded Groovy from 1.0-JSR-6 to 1.0 and started getting "No signature of method: static ... for argument types: ..." errors.  Upgrading further to version 1.1-beta3 exhibited the same behavior.  As an example, the following Groovy script will generate an error using Groovy version 1.0:

class S1 {
static String concat(String s, String c) {
  return s + c
}
}

class S2 extends S1 {
  static String concat(String s, Integer i) {
    return s + i
  }
}

println "Calling S2.concat(String,Integer) ..."
println S2.concat('foo', 1)
def m = S2.getMethod('concat', [String, String] as Class[])
println "S2.concat(String,String)=${m}\n\nCalling S2.concat(String,String) ..."
println S2.concat('foo', '1')

After a bit of searching, I found a Groovy Jira issue which explains the Groovy behavior for static method calls on subclasses is that "a static method is callable only on the class it is defined on."  This means care must be taken to ensure subclass inherited static method calls are avoided in certain versions of Groovy.

A number of approaches to get around this are:

  1. If you can, upgrade to Groovy version 1.1-RC1 which allows inherited static method calls.
  2. Change all inherited static method calls to use the class in which the static method is declared.
  3. Change all inherited static method calls to use an instance method call.
  4. Modify the subclass to include static methods delegating to the superclass static methods.
  5. Use Groovy version 1.0-JSR-6.

Java developers are accustomed to subclasses inheriting static methods from their superclass.  So Groovy's behavior with static methods should not be overlooked as a Groovy gotcha.  I've tested this behavior in versions 1.0-JSR-6, 1.0 and 1.1-beta3. 

UPDATE: Moments after posting this blog, Groovy version 1.1-RC1 was released.  I tested version 1.1-RC1 today (2007/10/14) and have found the above snippet will work properly.  Looking at the groovy.lang.MetaClassImpl.invokeStaticMethod() code shows that static methods are now being searched for by traversing up the class hierarchy.

No comments:

Post a Comment