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:
[java][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[/java]
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:[xml]<module>
<source path="">
<include name="**/MyEntity.java"/>
</source>
</module>[/xml] - 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
:
[xml]<resources>
<resource>
<directory>${basedir}/src/java</directory>
<includes>
<include>**/MyEntity.java</include>
</includes>
</resource>
</resources>[/xml] - 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:[xml]<inherits name=’com.lalou.jonathan.MyDependedProject’ />[/xml]
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:
[java]@RemoteServiceRelativePath("fooService")
public interface FooService extends RemoteService {
public String getHelloFoo(String totoName);
}[/java]
Create another interface for asynchronous call. You can notice the method name differs lightly from the one in the other interface:
[java]public interface FooServiceAsync {
void getHelloFoo(String fooName, AsyncCallback<String> callback);
}[/java]
Under the *.gwt.server
folder, create an implementation for service interface:
[java]public class FooServiceImpl extends RemoteServiceServlet implements FooService {
public FooServiceImpl() {
// TODO init
}
public String getHelloFoo(String fooName) {
// TODO call actual service
return "hello world!";
}
}[/java]
In the web.xml
file, add the following blocks:
[xml] <!– 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>
[/xml]
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:
[java]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);
}
});
[/java]
Now you can compile, package your war
and deploy under Tomcat or WebLogic.
NB: special to “black-belt GWT guy” David Chau from SFEIR.