title: GWT Simple RPC use case problem : Code included
body: <p>I am trying to work out how to send a domain object from the server-side to the client-side using GWT RPC. I've coded a really simple use case that represents the sort of thing I (and others?) need to be able to do but presently can't get to work.</p>
  
  <p>I have scoured the docs, tutorials and forums but they either show Strings being passed around or offer explanations that (when I apply them to this) still don't work.</p>
  
  <p>Hopefully someone can explain to me and others why this code doesn't work and how to get it to work.</p>
  
  <p>Thank you.</p>
  
  <p>Here are the error messages.</p>
  
  <pre><code>13:12:54.328 [DEBUG] [org.redboffin.worldhug.Test] Validating newly compiled units
  13:12:54.328 [ERROR] [org.redboffin.worldhug.Test] Errors in 'file:/C:/Documents%20and%20Settings/Darren/workspace/WorldHug/src/org/redboffin/worldhug/client/test/TestService.java'
  13:12:54.343 [ERROR] [org.redboffin.worldhug.Test] Line 14: No source code is available for type org.redboffin.worldhug.server.test.TestObject; did you forget to inherit a required module?
  13:12:54.515 [ERROR] [org.redboffin.worldhug.Test] Errors in 'file:/C:/Documents%20and%20Settings/Darren/workspace/WorldHug/src/org/redboffin/worldhug/client/test/TestServiceAsync.java'
  13:12:54.515 [ERROR] [org.redboffin.worldhug.Test] Line 12: No source code is available for type org.redboffin.worldhug.server.test.TestObject; did you forget to inherit a required module?
  13:12:55.953 [ERROR] [org.redboffin.worldhug.Test] Errors in 'file:/C:/Documents%20and%20Settings/Darren/workspace/WorldHug/src/org/redboffin/worldhug/client/test/TestView.java'
  13:12:55.968 [ERROR] [org.redboffin.worldhug.Test] Line 42: No source code is available for type org.redboffin.worldhug.server.test.TestObject; did you forget to inherit a required module?
  13:12:55.968 [ERROR] [org.redboffin.worldhug.Test] Line 46: No source code is available for type org.redboffin.worldhug.server.test.InnerObject; did you forget to inherit a required module?
  13:12:55.984 [ERROR] [org.redboffin.worldhug.Test] Line 48: No source code is available for type org.redboffin.worldhug.server.test.ListObject; did you forget to inherit a required module?
  13:12:56.765 [INFO] [org.redboffin.worldhug.Test] Module org.redboffin.worldhug.Test has been loaded
  </code></pre>
  
  <p>Here are the project classes and files.</p>
  
  <p>Test.gwt.xml</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
  &lt;!DOCTYPE module PUBLIC "-//Google Inc.//DTD Google Web Toolkit 2.0.0//EN" "http://google-web-toolkit.googlecode.com/svn/tags/2.0.0/distro-source/core/src/gwt-module.dtd"&gt;
  &lt;module&gt;
      &lt;inherits name="com.google.gwt.user.User" /&gt;
      &lt;source path="client/test" /&gt;
      &lt;entry-point class="org.redboffin.worldhug.client.test.Test"&gt;&lt;/entry-point&gt;
  &lt;/module&gt;
  </code></pre>
  
  <p>Web.xml</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
  &lt;!DOCTYPE web-app
  PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
  "http://java.sun.com/dtd/web-app_2_3.dtd"&gt;
  
  &lt;web-app&gt;
  
    &lt;!-- Servlets --&gt;
  
    &lt;servlet&gt;
      &lt;servlet-name&gt;testServlet&lt;/servlet-name&gt;
      &lt;servlet-class&gt;org.redboffin.worldhug.server.test.TestServiceImpl&lt;/servlet-class&gt;
    &lt;/servlet&gt;
  
    &lt;servlet-mapping&gt;
      &lt;servlet-name&gt;testServlet&lt;/servlet-name&gt;
      &lt;url-pattern&gt;/worldhug/test/testService&lt;/url-pattern&gt;
    &lt;/servlet-mapping&gt;
  
    &lt;!-- Default page to serve --&gt;
    &lt;welcome-file-list&gt;
      &lt;welcome-file&gt;test.html&lt;/welcome-file&gt;
    &lt;/welcome-file-list&gt;
  
  &lt;/web-app&gt;
  </code></pre>
  
  <p>TestObject.java</p>
  
  <pre><code>package org.redboffin.worldhug.server.test;
  
  import java.util.ArrayList;
  import java.util.List;
  
  import com.google.gwt.user.client.rpc.IsSerializable;
  
  public class TestObject implements IsSerializable {
  
      private String testObjectString;
      private InnerObject innerObject;
      private List&lt;ListObject&gt; listObjects = new ArrayList&lt;ListObject&gt;();
  
      public TestObject() {}
  
      // Getters and setters removed for brevity
  
  }
  </code></pre>
  
  <p>InnerObject.java</p>
  
  <pre><code>package org.redboffin.worldhug.server.test;
  
  import com.google.gwt.user.client.rpc.IsSerializable;
  
  public class InnerObject implements IsSerializable {
  
      private String innerObjectString;
  
      public InnerObject() {}
  
          // Getters and setters removed for brevity
  
  }
  </code></pre>
  
  <p>ListObject.java</p>
  
  <pre><code>package org.redboffin.worldhug.server.test;
  
  import com.google.gwt.user.client.rpc.IsSerializable;
  
  public class ListObject implements IsSerializable {
  
      private String listObjectString;
  
      public ListObject() {}
  
          // Getters and setters removed for brevity.
  
  }
  </code></pre>
  
  <p>TestService.java</p>
  
  <pre><code>package org.redboffin.worldhug.client.test;
  
  import org.redboffin.worldhug.server.test.TestObject;
  
  import com.google.gwt.user.client.rpc.RemoteService;
  import com.google.gwt.user.client.rpc.RemoteServiceRelativePath;
  
  /**
   * The client side stub for the Test Service.
   * @author Darren
   */
  @RemoteServiceRelativePath("testService")
  public interface TestService extends RemoteService {
  
      TestObject test();
  
  }
  </code></pre>
  
  <p>TestServiceAsync.java</p>
  
  <pre><code>package org.redboffin.worldhug.client.test;
  
  import org.redboffin.worldhug.server.test.TestObject;
  
  import com.google.gwt.user.client.rpc.AsyncCallback;
  
  /**
   * The async counterpart of &lt;code&gt;TestService&lt;/code&gt;.
   * @author Darren
   */
  public interface TestServiceAsync {
  
      void test(AsyncCallback&lt;TestObject&gt; callback);
  
  }
  </code></pre>
  
  <p>TestServiceImpl.java</p>
  
  <pre><code>package org.redboffin.worldhug.server.test;
  
  import java.util.List;
  
  import org.redboffin.worldhug.client.test.TestService;
  
  import com.google.gwt.user.server.rpc.RemoteServiceServlet;
  
  /**
   * The server side implementation of the RPC service.
   * @author Darren
   */
  @SuppressWarnings("serial")
  public class TestServiceImpl extends RemoteServiceServlet implements TestService {
  
      @Override
      public TestObject test() {
  
          TestObject testObject = new TestObject();       
          testObject.setTestObjectString("Test Object String");
  
          InnerObject innerObject = new InnerObject();
          innerObject.setInnerObjectString("Inner Object String");
  
                  testObject.setInnerObject(innerObject);
  
          List&lt;ListObject&gt; listObjects = testObject.getListObjects();
  
          ListObject listObjectOne = new ListObject();
          listObjectOne.setListObjectString("List Object One");
          listObjects.add(0, listObjectOne);
  
          ListObject listObjectTwo = new ListObject();
          listObjectTwo.setListObjectString("List Object Two");
          listObjects.add(0, listObjectTwo);
  
          ListObject listObjectThree = new ListObject();
          listObjectThree.setListObjectString("List Object Three");
          listObjects.add(0, listObjectThree);
  
          return testObject;
      }
  
  }
  </code></pre>
  
  <p>TestView.java</p>
  
  <pre><code>package org.redboffin.worldhug.client.test;
  
  import java.util.ArrayList;
  import java.util.Iterator;
  
  import org.redboffin.worldhug.server.test.InnerObject;
  import org.redboffin.worldhug.server.test.ListObject;
  import org.redboffin.worldhug.server.test.TestObject;
  
  import com.google.gwt.core.client.GWT;
  import com.google.gwt.event.dom.client.ClickEvent;
  import com.google.gwt.uibinder.client.UiBinder;
  import com.google.gwt.uibinder.client.UiField;
  import com.google.gwt.uibinder.client.UiHandler;
  import com.google.gwt.user.client.rpc.AsyncCallback;
  import com.google.gwt.user.client.ui.Button;
  import com.google.gwt.user.client.ui.Composite;
  import com.google.gwt.user.client.ui.Label;
  import com.google.gwt.user.client.ui.VerticalPanel;
  
  public class TestView extends Composite {
  
      private static TestViewUiBinder uiBinder = GWT.create(TestViewUiBinder.class);
  
      interface TestViewUiBinder extends UiBinder&lt;VerticalPanel, TestView&gt; {}
  
      @UiField Label testObjectStringLabel;
      @UiField Label innerObjectStringLabel;
      @UiField VerticalPanel listObjectsPanel;
      @UiField Button button;
      @UiField Label errorMessageLabel;
  
      public TestView(String firstName) {
          initWidget(uiBinder.createAndBindUi(this));
      }
  
      @UiHandler("button")
      void onClick(ClickEvent e) {
  
          TestServiceAsync testService = (TestServiceAsync) GWT.create(TestService.class);
  
          AsyncCallback&lt;TestObject&gt; callback = new AsyncCallback&lt;TestObject&gt;() {
  
              public void onSuccess(TestObject testObject) {
                  testObjectStringLabel.setText(testObject.getTestObjectString());
                  InnerObject innerObject = testObject.getInnerObject();
                  innerObjectStringLabel.setText(innerObject.getInnerObjectString());
                  ArrayList&lt;ListObject&gt; listObjects = (ArrayList&lt;ListObject&gt;) testObject.getListObjects();
                  Iterator&lt;ListObject&gt; iterator = listObjects.iterator();
                  while(iterator.hasNext()) {
                      ListObject listObject = (ListObject) iterator.next();
                      listObjectsPanel.add(new Label(listObject.getListObjectString()));
                  }
              }
  
              public void onFailure(Throwable caught) {
                  errorMessageLabel.setText("Error : "+caught.getMessage());
              }
            };
  
            testService.test(callback);
  
      }
  
  }
  </code></pre>
  
  <p>TestView.ui.xml</p>
  
  <pre><code>&lt;!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent"&gt;
  &lt;ui:UiBinder 
      xmlns:ui="urn:ui:com.google.gwt.uibinder"
      xmlns:g="urn:import:com.google.gwt.user.client.ui"&gt;
  
      &lt;g:VerticalPanel&gt;
          &lt;g:Label&gt;Test Object&lt;/g:Label&gt;
          &lt;g:Label ui:field="testObjectStringLabel"&gt;&lt;/g:Label&gt;
          &lt;g:VerticalPanel&gt;
              &lt;g:Label&gt;Inner Object&lt;/g:Label&gt;
              &lt;g:Label ui:field="innerObjectStringLabel"&gt;&lt;/g:Label&gt;
          &lt;/g:VerticalPanel&gt;
          &lt;g:VerticalPanel ui:field="listObjectsPanel"&gt;
              &lt;g:Label&gt;List Objects&lt;/g:Label&gt;
          &lt;/g:VerticalPanel&gt;
          &lt;g:Button ui:field="button"&gt;Display Test Object&lt;/g:Button&gt;
          &lt;g:Label ui:field="errorMessageLabel"&gt;&lt;/g:Label&gt;
      &lt;/g:VerticalPanel&gt;
  
  &lt;/ui:UiBinder&gt;
  </code></pre>
  
  <p>Thank you for reading this far and for any help you may be able to give me (and others).</p>