February 9, 2010 49 Comments
I should have published this sooner when my colleague (Radovan Sninský, working with me on Java Simon among other things) came with the solution how to call Seam components from GWT 2 (probably in milestone 1 already). GWT 2.0.0 changed some details in its RPC protocol and built-in Seam support for GWT stopped working with errors like this:
2010-02-09 10:28:12,265 ERROR [org.apache.catalina.core.ContainerBase.[jboss.web].[localhost].[/whatever]] (http-127.0.0.1-8080-1) An IncompatibleRemoteServiceException was thrown while processing this call. com.google.gwt.user.client.rpc.IncompatibleRemoteServiceException: Parameter 0 of is of an unknown type 'some.Class/some number' at org.jboss.seam.remoting.gwt.GWTService.RPC_decodeRequest(GWTService.java:426) at org.jboss.seam.remoting.gwt.GWTService.processCall(GWTService.java:203) at org.jboss.seam.remoting.gwt.GWTService$1.process(GWTService.java:120) at org.jboss.seam.servlet.ContextualHttpServletRequest.run(ContextualHttpServletRequest.java:53) at org.jboss.seam.remoting.gwt.GWTService.getResource(GWTService.java:105) at org.jboss.seam.servlet.SeamResourceServlet.service(SeamResourceServlet.java:80) ... Caused by: java.lang.ClassNotFoundException: some.Class/number at java.lang.Class.forName0(Native Method) at java.lang.Class.forName(Class.java:247) at org.jboss.seam.remoting.gwt.GWTService.RPC_getClassFromSerializedName(GWTService.java:479) at org.jboss.seam.remoting.gwt.GWTService.RPC_decodeRequest(GWTService.java:422) ... 46 more
As GWT 2.0 is fresh it was obviously better to patch Seam. And because GWT calls are processed using awesome Seam Adapters (I really like this concept!) we decided to duplicate the existing Adapter and just rewriting problematic parts. The RPC protocol changes were very subtle but it was big enough to blow out in case of Long types and probably some others too. Radovan then copied a few classes from Seam and added some of his code, fixed some lines and registered his GWT Service adapter on the URL suffix /gwt2. That way the only thing you need to do in your project is:
- download this ZIP
- unzip it into your src directory and let it be compiled along with EJB part of your application – if you move classes to another package, fix package declaration as well in all 5 classes
- change the method in GWT UI part where you retrieve the service point – for example:
SomeServiceAsync svc = GWT.create(SomeService.class); ((ServiceDefTarget) svc).setServiceEntryPoint(GWT.getHostPageBaseURL() + "seam/resource/gwt2");
The important part is “gwt2″ at the end instead of “gwt”. If you have your URL in some constant, change it there. Recompile, rebuild, redeploy, restart, try it – it should work now. Of course – if you’re really using GWT 2.0.0.
Licensing? Well… I guess it is LGPL like the original Seam sources. Hopefully there is no Seam 2.3 with GWT 2 support around the corner (doesn’t seem so) which would render this post useless in a day.