Posts Tagged ‘RPC’
No source code is available for type … ; did you forget to inherit a required module?
Context
In a GWT application, you have to use RPC calls, using entities which are package in external jar archives. With Eclipse, no error appears ; yet when you build the project with Maven2, you get this message:
[INFO] [ERROR] Errors in 'file:/C:/eclipse/workspace/myGwtProject/src/java/com/lalou/jonathan/web/gwt/client/component/JonathanPanel.java' (...) [INFO] [ERROR] Line 24: No source code is available for type com.lalou.jonathan.domain.MyEntity; did you forget to inherit a required module? (...) [INFO] Finding entry point classes
Fix
In related jar
In the project to which MyEntity
belongs to (here: my/depended/project
):
- create a file
com/lalou/jonathan/MyDependedProject.gwt.xml
, with as content:<module> <source path=""> <include name="**/MyEntity.java"/> </source> </module>
- In the pom.xml:
- Add the source
MyEntity.
java
in built jar. This way, the Java file itself will be considered as a resource, like an XML or property file. To perform this, the quickest manner is to add the following block in thepom.xml
:<resources> <resource> <directory>${basedir}/src/java</directory> <includes> <include>**/MyEntity.java</include> </includes> </resource> </resources>
- Add an
<include>**/*.gwt.xml</include>
so that to have toMyDependedProject.gwt.xml
file in the built jar.
In GWT project
In your
*.gwt.xml
file, add the dependency:<inherits name='com.lalou.jonathan.MyDependedProject' />
Caution!
All these operations need be done on all dependencies -either direct or indirect-. Therefore, possibly you may have a huge amount of code to be got.
Another issue appears when you use a jar of which you do not have the source code, such as in the case of tiers API for instance. - Add the source
Basic RPC call with GWT
Let’s assume you have a “Hello World” GWT application. You need emulate a basic RPC call (RMI, EJB, etc.). Here is the program:
Under the *.gwt.client folder
:
Create an service interface:
@RemoteServiceRelativePath("fooService") public interface FooService extends RemoteService { public String getHelloFoo(String totoName); }
Create another interface for asynchronous call. You can notice the method name differs lightly from the one in the other interface:
public interface FooServiceAsync { void getHelloFoo(String fooName, AsyncCallback<String> callback); }
Under the *.gwt.server
folder, create an implementation for service interface:
public class FooServiceImpl extends RemoteServiceServlet implements FooService { public FooServiceImpl() { // TODO init } public String getHelloFoo(String fooName) { // TODO call actual service return "hello world!"; } }
In the web.xml
file, add the following blocks:
<!-- Servlets --> <servlet> <servlet-name>fooService</servlet-name> <servlet-class>com.......server.FooServiceImpl</servlet-class> </servlet> <servlet-mapping> <servlet-name>fooService</servlet-name> <url-pattern>/ivargwt/fooService</url-pattern> </servlet-mapping>
The tags content match the argument given as parameter to RemoteServiceRelativePath
annotation above.
From then, in your concrete code, you can instantiate the service and call remote method:
FooServiceAsync fooService = GWT.create(FooService.class); fooService.getHelloFoo("how are you?", new AsyncCallback<String>() { public void onSuccess(String result) { MessageBox.alert("OK", result, null); } public void onFailure(Throwable caught) { MessageBox.alert("ERROR", "rpc call error-" + caught.getLocalizedMessage(), null); } });
Now you can compile, package your war
and deploy under Tomcat or WebLogic.
NB: special to “black-belt GWT guy” David Chau from SFEIR.