This last week I was concentrated in developing a J2ME application that communicates with a Web Service to gather some information about route planning. Basically, the mobile app ask for a route, given an origin and a destination waypoints. Although this kind of work looks very easy, I got some problems to accomplish it. Due to that, I will share here my experiences to save you some time and if you have a different solution for creating J2ME web service clients, please let me know.
First of all, you will need the following softwares:
-
NetBeans IDE: instead of my fanatism for Eclipse IDE, I used NetBeans due to its facilities in creating web services.
-
Sun Java Wireless Toolkit: java toolkit for creating mobile applications.
-
Apache Tomcat: my target Web Server. Remember to download the .zip version.
The first step is creating the Web Service. So, inside NetBeans IDE, I will configure my tomcat installation under Tools->Servers menu option. (I’m using the pt_BR version of netbeans, so the menus may be a little different). Next, I choose Add Server and type the tomcat’s path location in my local machine. (Neatbeans comes with a native Web Server called GlassFish. If you are not aware with web server now, use this configuration as default).
Later, I have to create my web application project. So, under File->New Project menu, I choose Java Web category and Web Application project type. Click on “next” until your configuration has finished. Now, it’s time to create you source. I will show here a similar implementation of my route server.
Here I show the Waypoint class.
package entities;
public class Waypoint {
private double lat;
private double lng;
public Waypoint(double lat, double lng) {
this.lat = lat;
this.lng = lng;
}
public Waypoint() {
}
public double getLat() {
return lat;
}
public void setLat(double lat) {
this.lat = lat;
}
public double getLng() {
return lng;
}
public void setLng(double lng) {
this.lng = lng;
}
}
Here I show the Route class.
package entities;
public class Route {
private Waypoint[] waypoints;
public Route(Waypoint[] waypoints) {
this.waypoints = waypoints;
}
public Route() {
}
public Waypoint[] getWaypoints() {
return waypoints;
}
public void setWaypoints(Waypoint[] waypoints) {
this.waypoints = waypoints;
}
}
Notice that I’m using complex object and arrays, which are in the most cases the reason of a lot of problems in deploying Web Services.
Next, I create my Web Service. To do that, right-click on the package folder and choose New->WebService. Here I show the implementation of my Web Service, which just return a route created by the given latitudes and longitudes.
package webservice;
import entities.Route;
import entities.Waypoint;
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebService;
/**
*
* @author Fernando Kakimoto
*/
@WebService()
public class RouteService {
/**
* Operação de serviço web
*/
@WebMethod(operationName = "getRoute")
public Route getRoute(@WebParam(name = "oLat", partName="oLatPart") double oLat,
@WebParam(name = "oLng", partName="oLngPart") double oLng,
@WebParam(name = "dLat", partName="dLatPart") double dLat,
@WebParam(name = "dLng", partName="dLngPart") double dLng) {
Waypoint w1 = new Waypoint(oLat, oLng);
Waypoint w2 = new Waypoint(dLat, dLng);
Waypoint[] waypoints = new Waypoint[]{w1, w2};
return new Route(waypoints);
}
}
After project compilation, the project tree will be similar than the picture below:

The Web Service is done. It’s time to create our J2ME client. For that, there are some options. One option is using the netbeans native support for that. After created a J2ME project, inside the New->J2ME Client for Web Applications menu, you are able to select a WSDL file as source and the IDE creates the J2ME client code for you. However, I tried this approach and the generated code came with errors. So, I used the second option: Sun Java Wireless Toolkit.
The WTK offers some utilites under File->Utilities menu. One of them is the Stub Generator, which generates J2ME client code for your WSDL service. So, run your service inside NetBeans or create its respective WSDL file. Next, in the stub generator, type the file path or URL, the code destination and the CLDC version. Here is how my Stub Generator looks like.

After the code generation, here is the result of my WebClient J2ME project.

To finish, all you have to do is instantiate RouteService_Stub class and invoke getRoute() method. To make things simple, I used just one class which corresponds to the midlet. Here is the midlet code.
package main;
import client.Route;
import client.RouteService;
import client.RouteService_Stub;
import client.Waypoint;
import java.rmi.RemoteException;
import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.Form;
import javax.microedition.midlet.*;
/**
* @author Fernando Kakimoto
*/
public class MainMidlet extends MIDlet implements CommandListener {
private Command exitCommand = new Command("Exit", Command.EXIT, 1);
private Form form = new Form("J2ME Web Client");
public void startApp() {
try {
RouteService service = new RouteService_Stub();
Route r = service.getRoute(1.5, 2.5, 1.8, 2.8);
Waypoint origin = r.getWaypoints()[0];
Waypoint detination = r.getWaypoints()[1];
form.append("origin:" + origin.getLat() + "," + origin.getLng());
form.append("\n");
form.append("destination:" + detination.getLat() + "," + detination.getLng());
form.addCommand(exitCommand);
form.setCommandListener(this);
Display.getDisplay(this).setCurrent(form);
} catch (RemoteException ex) {
ex.printStackTrace();
}
}
public void pauseApp() {
}
public void destroyApp(boolean unconditional) {
}
public void commandAction(Command c, Displayable d) {
if(c == exitCommand){
destroyApp(false);
}
}
}
That’s it. Simple and working.
The result you can see running the midlet sample.
See you,
–
Fernando

