Sonntag, 13. März 2011

GWT: Calling RPC Service inside another module

Problem description: I have a module B, which inherits module A. When I call RPC Services from A inside A, they work ok. But when I call the services from A in B, the RPC invocations always fail.

Solution: Normally when you create a RPC Service inside your GWT application, the default GWT RPC service (Servlet) endpoint is @RemoteServiceRelativePath("some_name") which you have to define in your class inheriting from RemoteService. For example:

@RemoteServiceRelativePath("sessionService")
public interface SessionService extends RemoteService {...}

which resolves to /module_base/some_name at runtime on the client. The biggest problem in this approach is: let's say this class (SessionService) was defined in Module A, if you call the services (methods) from this class in Module B, they will NOT work.  That happens cause your RPC endpoint is now tied to GWT Module (A). To get rid of this, you have to create a static instance of the service endpoint and also seed it with the right endpoint; something like this:

import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.rpc.ServiceDefTarget;

public class ServicesFactory {
    public static final SessionServiceAsync SessionService = GWT
            .create(SessionService.class);

    static {
        ((ServiceDefTarget) SessionService).setServiceEntryPoint(GWT
                .getHostPageBaseURL() + SessionService.END_POINT);
    }
  
    public static void printEndPoint() {
        System.out.println(GWT
                .getHostPageBaseURL() + SessionService.END_POINT);
    }
}
Note that END_POINT is defined in the service interface itself. In my case it is "sessionService". 
Now, if you want to use the RPC services from Module A (which are define in the class SessionService), in module B, just use:

SessionServiceAsync sessionService = ServicesFactory.SessionService;

Thanks to the people from cloudglow for developing this method.