Surprised nobody hit this before, but SmartGWT 2.4 gets upset if you have a parent class with an abstract method signature, and that signature contains generics. It is definitely the method signature that is the issue, not the class signature (I did a bit of experimenting).
For anybody that does hit this, the kludgy workaround for the code below was to make fetch() concrete in the parent class, and invoke an abstract handleFetch method. Then the concrete method in the subclass was renamed to handleFetch.
Now for some details. I’m using DMI via Spring, and it worked fine until a recent bit of refactoring. For example with a DMI object UserDmi, and an abstract base class DmiBase as shown below:
public abstract class DmiBase<PK extends Serializable, E extends Entity<PK>> {
public abstract DSResponse fetch(DSRequest dsRequest, E criteria);
…
}
public class UserDmi extends DmiBase<String, User> {
@Override
public DSResponse fetch(DSRequest dsRequest, User criteria) {
log.info(“processing DMI fetch operation on {}”, criteria);
…
}
…
}
In the browser this just gets you a popup dialog with:
sun.reflect.generics.reflectiveObjects.TypeVariableImpl
cannot be cast to java.lang.Class
It looks like the isomorphic reflection class doesn’t handle some of the java generics implementation, apparently in this case TypeVariable. It doesn’t need to, if it just spots that it is dealing with an abstract method signature on the parent, instead of the overridden concrete method on the child. That should be obvious from the Modifier flags on the method.
The log is below. Notice that none of my code is yet in play, only SmartGWT’s attempt to do reflection on it.
=== 2011-05-26 14:15:55,521 [l0-6] INFO ServerObject - DMI on Spring bean: userDmi
=== 2011-05-26 14:15:55,521 [l0-6] WARN RequestContext - dsRequest.execute() failed:
java.lang.ClassCastException: sun.reflect.generics.reflectiveObjects.TypeVariableImpl cannot be cast to java.lang.Class
at com.isomorphic.base.VersionSafeChecker.getGenericParameterTypes(VersionSafeChecker.java:118)
at com.isomorphic.base.Reflection.adaptArgsAndInvoke(Reflection.java:782)
at com.isomorphic.datasource.DataSourceDMI.execute(DataSourceDMI.java:586)
at com.isomorphic.datasource.DataSourceDMI.execute(DataSourceDMI.java:64)
at com.isomorphic.datasource.DSRequest.execute(DSRequest.java:1440)
at com.isomorphic.servlet.IDACall.handleDSRequest(IDACall.java:173)
at com.isomorphic.servlet.IDACall.processRPCTransaction(IDACall.java:130)
at com.isomorphic.servlet.IDACall.processRequest(IDACall.java:95)
at com.isomorphic.servlet.IDACall.doPost(IDACall.java:54)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
at com.isomorphic.servlet.BaseServlet.service(BaseServlet.java:152)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:487)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1097)
at com.isomorphic.servlet.CompressionFilter.doFilter(CompressionFilter.java:259)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1088)
at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:360)
at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)
at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:181)
at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:729)
at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:405)
at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
at org.mortbay.jetty.handler.RequestLogHandler.handle(RequestLogHandler.java:49)
at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
at org.mortbay.jetty.Server.handle(Server.java:324)
at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:505)
at org.mortbay.jetty.HttpConnection$RequestHandler.content(HttpConnection.java:843)
at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:647)
at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:211)
at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:380)
at org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:395)
at org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:488)