Web services in the Java 2 Platform, Micro Edition (J2ME) platform, as defined by Java Specification Request 172 (JSR 172), follow the same specifications, architecture, and invocation model as with standard Web services. Let's review the checklist.
Compare with standard Web services
JSR 172 Web Services APIs (WSA) follow these core Web services specifications:
- Simple Object Access Protocol (SOAP) 1.1, which defines transport and data encoding.
- Web Services Definition Language (WSDL) 1.1, which defines how to describe remote services.
- XML 1.0, which defines the XML markup language; and
- XML Schema, which, of course, defines the XML schema.
Note that JSR 172 does not support the Universal Description, Discovery, and Integration (UDDI) 2.0 specification that defines how remote services are discovered.
Because there are quite a few specifications that cover different technologies related to Web services, and the number keeps growing, the Web Services Interoperability Organization (WS-I) has defined the WS-I Basic Profile, Version 1.0 to define the minimum set of Web services specifications, as well as conformance rules that all basic Web services providers and consumers must follow. The JSR 172 specification conforms to the WS-I Basic Profile.
Same architecture as standard Web services:
JSR 172 WSA approach Web services from the client, service-consumer perspective: WSA provide the remote service invocation API (JAX-RPC) and runtime environment that allow J2ME applications to consume services on the Web, but not to function as service producers (endpoints). Apart from this difference, the rest of the architecture follows the standard architecture/organization of Web services, as illustrated next:
Figure 1 - WSA high-level architecture
This high-level architecture is structured as follows:
- A client, Web services consumer: This is the J2ME application, such as MIDP or Personal Profile-based application, a JSR 172 stub and supporting classes, and the JSR 172 runtime.
- The network: This refers to the wireless and wired networks, part of the Internet, and the communication protocols. Note that JSR 172 does not mandate the use of XML encoding on the device itself, allowing implementations (as long as they're transparent to both consumer and producer) to use more efficient encoding approaches, such as the use of binary protocols between the device and the wireless gateway.
- The server, Web services producer: This is a Web server, typically behind firewalls and/or proxy gateways. This server might have access to back-end resources.
Same invocation model and data flow as standard Web services:
J2ME applications invoke remote services through the JSR 172 stub(s) and runtime, and typically over HTTP and SOAP. The stubs and runtime hide the complexities associated with remote service invocation including how input and return values are encoded and decoded, and the complexities related to managing network communication to the server. Method invocation follows the synchronous request-response model, as illustrated here:
Figure 2 - JSR 172 invocation model
*Because invocations are blocking calls, you should dispatch these in a separate thread of execution.
To consume a Web service, you must first create service invocation stubs. These stubs perform tasks, such as encoding and decoding of input and return values, and interfacing with the JSR 172 runtime to invoke the a remote service endpoint. Stubs interface with the runtime through the Service Provider Interface (SPI) of the runtime, which abstracts runtime implementations details, allowing portability of stubs between vendors implementations.
Stubs are typically generated using a tool that reads a WSDL XML document, which describes the Web service to be used. WSDL documents are, in turn, typically generated via a tool that reads interface definitions, such as Java Interfaces producing the WSDL document.
From our mobile development perspective, the WSDL document you want to consume will typically already exist, so all you have to do is generate the JSR 172 WSA stubs. To generate these stubs, you should use a tool such as the J2ME Wireless Toolkit 2.1 stub generator, shown here:
Figure 3: Generating a JSR 172 WSA stub
This generates the stub Java files, and related supporting classes. It also takes care of the WSDL-to-Java data type mapping, as described in the next section.
Once the JSR 172 JAX-RPC stub and supporting files have been generated, and your application has been compiled and deployed onto a JSR 172-enabled device, consuming Web services is very straightforward and almost transparent. As you'll see shortly, invoking remote methods is as almost as simple as invoking local ones.
The JSR 172 remote method invocation API is based on a subset of the J2SE Java API for XML-based RPC (JAX-RPC 1.1). It also conforms to WS-I Basic Profile. Here's a look at the JSR 172 JAX-RPC subset API in more detail:
It supports:
- SOAP 1.1.
- Any transport that can deliver SOAP messages, such as HTTP 1.1, which has a defined protocol binding for SOAP 1.1.
- The literal representation of a SOAP message representing an RPC call or response.
The following data types and corresponding Java mapping: xsd:booleantobooleanorBoolean.xsd:bytetobyteorByte.xsd:shorttoshortorShort.xsd:inttointorInteger.xsd:longtolongorLong.xsd:floattofloat, orFloat. For CLDC 1.0-based platforms, this data type maps to String.xsd:doubletodouble, orDouble. For CLDC 1.0-based platforms, this data type maps to String.xsd:stringtoString.xsd:base64Binarytobyte[].xsd:hexBinarytobyte[].xsd:complexTypeto Sequence of primitive and class types.xsd:QNametojavax.xml.namespace.QName.- Arrays of primitive types and complex types (structures containing primitive or complex types) based on the schema of the XML array.
It does not support:
- SOAP messages with attachments.
- SOAP message handlers.
- Encoded representation of a SOAP message.
- Service endpoints (no Web service producer).
- Service discovery support (UDDI).
XML encoding is not mandated at the device either. This is to help reduce network traffic by allowing implementations to use more efficient data encoding, such as a binary protocol between the device and the wireless gateway, as long as such encoding is transparent to both the Web service consumer and the producer.
The JSR 172 remote invocation API consists of the following packages:
javax.microedition.xml.rpcjavax.xml.namespacejavax.xml.rpcjava.rmi(included to satisfy JAX-RPC dependencies)
Note that these APIs (with some exceptions, such as RemoteException) are not used directly by the application, which uses the generated stubs instead. The above APIs are mainly for stub use. Please refer to the JSR 172 specification and/or Javadoc for details.
Invoking remote services using JSR 172 JAX-RPC
Once your JSR 172 JAX-RPC stub and supporting files have been generated, compiled, and deployed, consuming remote services is very easy. As a matter of fact, apart from importing RemoteException and doing minimal JAX-RPC specific initialization, your application looks and behaves almost exactly as a non-Web service consumer application. This simplicity is possible due to the JSR 172 stub and runtime, which, as previously mentioned, hide most of the details related to remote invocation.
To invoke a remove service, you first instantiate the stub and perform minimal stub initialization; then it is a matter of invoking the stub's methods. The following code snippet shows how to invoke a remote service using JSR 172 JAX-RPC.
Listing 1: Invoking a remote service
package j2medeveloper.wsasample
// MIDP
import javax.microedition.midlet.MIDlet;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Form;
...
Form form = new Form("Employee Info");
...
// JAX-RPC
import java.rmi.RemoteException;
String serviceURL = "www.j2medeveloper.com/webservicesample";
...
/**
* Entry point to MIDlet, from start or restart states.
* @throws javax.microedition.midlet.MIDletStateChangeException
*/
public void startApp() throws MIDletStateChangeException {
// Instantiate the service stub.
EmployeeService_Stub service = new EmployeeService_Stub();
// Initialize the stub/service.
service._setProperty(Stub.ENDPOINT_ADDRESS_PROPERTY,
serviceURL);
service._setProperty(Stub.SESSION_MAINTAIN_PROPERTY, new
Boolean(true));
...
display.setCurrent(mainScreen);
}
/**
* Paused state. Release resources (connection, threads, etc).
*/
public void pauseApp() {
...
}
/**
* Destroy state. Release resources (connection, threads, etc).
* @param uc If true when this method is called, the MIDlet must
* cleanup and release all resources. If false the MIDlet may
* throw MIDletStateChangeException to indicate it does not want
* to be destroyed at this time.
* @throws javax.microedition.midlet.MIDletStateChangeException
* to indicate it does not want to be destroyed at this time.
*/
public void destroyApp(boolean uc) throws MIDletStateChangeException {
...
}
:
:
/**
* Command Listener.
* @param c is the LCDUI Command.
* @param d is the source Displayable.
*/
public void commandAction(Command c, Displayable d) {
if (c == UiConstants.COMMAND_GET_EMPINFO) {
Thread th = new Thread(new GetEmpInfoTask());
th.start();
} else {
...
}
:
:
}
/**
* On its own thread, invoke the remote service getEmployeeInfo
*/
public class GetEmpInfoTask implements Runnable {
public void run() {
try {
// Invoke the remote service.
EmployeeInfo empInfo =
service.getEmployeeInfo(empId);
:
:
// Display the employee Information
form.append("Name:" +
empInfo.firstname+empInfo.lastname);
form.append("Status:"+empInfo.status);
:
:
display.setCurrent(form);
} catch (RemoteException e) {
// Handle RMI exception.
} catch (Exception e) {
// Handle exception.
}
}
}
:
:
|
Note how the remote invocation was performed in its own thread of execution. This is because remote invocations in JSR 172 are blocking calls, and if invoked in the main event thread, the user interface will freeze until the remote invocation completes.
You have just studied the generation of a JSR 172 JAX-RPC stub. From here, please refer to the appropriate stub generator documentation for more information.
This article introduced the JSR 172 WSA for the J2ME platform, with emphasis on the JAX-RPC for J2ME remote service invocation APIs. In addition, I covered the core Web services standards and the typical architecture and invocation model used in JSR 172 WSA. I also reviewed how to consume Web services, the JAX-RPC subset API, with a short code example included.
In the second part of this article, I will talk about the JSR 172 XML parsing API.
- Visit the JCP site for more information on the JCP JSR 172 specification.
- Download the J2ME Wireless Toolkit 2.1.
- The WS-I Basic Profile Version 1.0 specification is available on the WS-I site.
- This free tutorial instructs you on how to "Develop Web services clients for mobile devices" (developerWorks, March 2004).
- Get more developing know-how from the article "Cross-platform programming with Java technology and the IBM Web Services Toolkit for Mobile Devices" (developerWorks, February 2003).
- Read Simple Object Access Protocol (SOAP) 1.1, which defines transport and data encoding.
- Check out Web Services Definition Language (WSDL) 1.1, which defines how to describe remote services.
- Read XML 1.0, which defines the XML markup language.
- Read XML Schema for a definition of the XML schema.
- Keep up with more technology by subscribing to the IBM WebSphere Developer Technical Journal.
C. Enrique Ortiz co-designed the Sun Microsystems' Mobile Java Developer Certification Exam, and is an active participant in the wireless Java community and in various J2ME expert groups. He is a software architect and developer, and a wireless mobility technologist and writer who has authored and co-authored many publications. Enrique holds a B.S. in Computer Science from the University of Puerto Rico and has more than 15 years of software engineering, product development, and management experience.
Comments (Undergoing maintenance)





