'Why does the @Override annotation not work when building a Grails project?

I'm using the Grails 2.3.8 build system to build my Grails project (i.e., the default system built on top of Gant).

When I annotate my methods with @java.lang.Override, Grails doesn't fail compilation even if the method overrides nothing in the parent classes.

When I compile directly using groovyc, things work fine.

Is there a compilation option I haven't enabled? :)



Solution 1:[1]

Grails 2.3.8 uses Groovy 2.1.9. In that version of Groovy the @Override annotation is not honored in (at least) the situation I was using it (the most basic case):

class A {
        def foo() {}
}


class B extends A {
        @Override
        def foo(String s) {}

}

In that version of Groovy (2.1.9) the above code compiles just fine.

Then I downloaded the latest version of Groovy (as of now, 2.4.1) and tried compiling the same class. The compiler threw an error as I expected:

org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:
foo.groovy: 7: Method 'foo' from class 'B' does not override method from its superclass or interfaces but is annotated with @Override.
 @ line 7, column 2.
        @Override
    ^

1 error

UPDATE: There actually are two ways in which even Groovy 2.1.9 honors @Override:

  1. If the access modifier does not match (public, protected, private)
  2. If the method return type does not match

Solution 2:[2]

While upgrading Grails and, by extension, Groovy on a legacy system this error started to happen in lots of places. The generic class had a method which was being overridden anonymously in the code. The problem was that on instantiation the generic type wasn't filled. As @Override wasn't honored before, it worked. When I upgraded this error started to happen. I fixed it specifying the type for the generic class.

Example:

class Base<T> {
  void foo(T t) {}
}

Object was being instantiated like this:

def base = new Base() {
  @Override
  void foo(String string) {}
}

Fixed specifying the type for the generic class:

def base = new Base<String>() {
  @Override
  void foo(String string) {}
} 

Also, if you are having problems with @Override, check if the version doesn't have this bug.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2