Common Java Idiom, Lousy GWT Bug
I have to get around to shipping this one to the GWT committers, but this one bit me hard.
Let’s say you have interface Driveable:
public interface Driveable { public void accelerate(); public void brake(); public void tuneRadio(); }
Awesome. Now let’s say you have class AbstractDriveable:
public abstract class AbstractDriveable implements Driveable { public void accelerate() { Window.alert("Vroom vroom!"); } public void brake() { Window.alert("Screeeeeech!"); } }
Totally cool. And then you love your favorite FM station in ConcreteDriveable:
public class ConcreteDriveable extends AbstractDriveable { public void tuneRadio() { Window.alert("Rockin' the oldies!"); } }
Then we launch into development mode with whatever our application is, and…something explodes.
So we debug, and upon looking at the code that cleverly calls tuneRadio polymorphically – we notice that our debugger drops into a catch block for a NoSuchMethodError.
It appears that GWT seems to lose track of this common idiom – use an interface to define behavior, realize that interface on an abstract class to create default behaviors, and then strategize those behaviors in concrete implementations.
The workaround is simple: redeclare your unrealized interface method in the abstract class. But this is a pretty nasty little bug. The GWT guys know this, but it’s rather critical to GWT that it follow the practices of Java as best as possible. Otherwise it’s YAL.