Fork me on GitHub
NOTICE There is a new plugin (archetypes and eclipse integration), a fresh start that correctly support multi-module projects, it is not version-bounded with GWT, support multiples GWT versions and other fixes, improvements and best practices. This plugin is now considered the legacy GWT maven plugin (aka mojo GWT maven plugin) and the new one is considered the new generation GWT maven plugin (aka tbroyer GWT maven plugin). The legacy maven plugin is still supported but it is strongly encouraged to use the new one for new projects.
TIP If you choose to migrate to the tbroyer plugin, you can use this alternative project to generate async interfaces using java annotation processor.

Generate Async interfaces for GWT-RPC services

About

GWT client will communicate with server-side components using GWT-RPC data serialization protocol. If you're not familiar with this please review the developper's guide.

The GWT-RPC model requires you to define two interfaces : one on server side to handle requests, and a sibling one on client side for invoking the RPC serialization process. The second one is asynchronous, and the two interfaces must match together.

Considering the following Remote Service interface :

import com.google.gwt.user.client.rpc.RemoteService;

@RemoteServiceRelativePath( "HelloWorld" )
public interface HelloWorldService
    extends RemoteService
{
    String helloWorld( String message );
}

The asynchrounous interface used on client-side code is :

public interface HelloWorldServiceAsync
{
    String helloWorld( String message, AsyncCallBack<String> callback );
}

gwt-maven-plugin includes a simple code generator to create all Async interfaces from your server-side remote service interfaces.

Generate Async interface for GWT-RPC services

The generateAsync goal will create a generate-sources folder and Async interface for all RemoteInterface found in the project. To avoid a full scan, only Java source files that matches a pattern are checked. Defaults is to only check **/*Service.java, but you can override this convention using the servicePattern parameter.

<project>
  [...]
  <build>
    <plugins>
      [...]
      <plugin>
        <groupId>org.codehaus.mojo</groupId>
        <artifactId>gwt-maven-plugin</artifactId>
        <version>2.8.1</version>
        <executions>
          <execution>
            <configuration>
              <servicePattern>**/gwt/**/*Service.java</servicePattern>
            </configuration>
            <goals>
              <goal>generateAsync</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
      [...]
    </plugins>
  </build>
  [...]
</project>

Utility class

The generated code includes an Utility nested class to retrieve the RemoteService async instance from client-side code. This avoid writing boiler plate code for getting RPC services from your GWT code.

public interface HelloWorldServiceAsync
{
    String helloWorld( String message, AsyncCallBack<String> callback );

    public static class Util
    {
        public static ContactPrefereServiceAsync getInstance()
        ...
    }
}

This utility class must know the server URI the Remote Service is exposed. The plugin will use @RemoteServiceRelativePath annotation on the service interface to set the URI in this utility class. In previous example, the service will be binded to URI [module]/HelloWorld.

If no annotation is set, the service URI is constructed from interface name applying the rpcPattern format. Setting this parameter to ".rpc" will create an Util class to bind the service to URI [module]/HelloWorldService.rpc.

The generateAsync goal also has a failOnError parameter that can be helpfull is you have issue with the generator.