Java Development News:
Using J2EE to Drive J2ME Applications
By David Hemphill
01 Jul 2002 | TheServerSide.com
Wireless technology is evolving at a rapid pace. There is a lot of talk about mobile and wireless computing and there is also a fair amount of hype. However, the one thing that is conspicuously absent from much of these discussions on mobile and wireless computing is a discussion on what these devices are connecting to. The fact is, most of the value, in terms of content and capabilities of the device, is a result of interacting with a server of some type. This is true whether we are talking about microbrowsers such as WAP and iMode, J2ME clients, or short message service (SMS) and email. Behind the scenes these devices are interacting with services that reside somewhere on a network. These services handle much of the complex details of the features offered by wireless devices. Although there are complexities that the mobile device must deal with, a well-designed wireless architecture delegates as much complexity as possible to the server. This is desirable because servers have more processing capabilities and do not have the power restrictions of mobile devices (i.e., servers don't run on batteries that are worn down by the CPU). This article examines wireless computing from the server's perspective. First, the problems of wireless computing or the public Internet are discussed. Then various models that help address these problems are provided.
Introducing wireless devices into an architecture comes with some challenges that are not present in a wire-based architectures. These challenges must be managed from the server as well as the device. Although there are a number of issues to consider, the three following issues are most critical when connecting to Internet-based services over a wireless connection.
- Bandwidth: The wireless networks available today are much slower than wire-line services. Connection speeds range from 2 kbps to about 20 kbps depending on the type of network and signal strength.
- Service availability: Wireless networks have dead spots and limited coverage outside of heavily populated areas. What's more, connections between a device and the server can drop unexpectedly if a user moves out of coverage or steps into a dead spot by walking into an elevator, entering a stairwell and so forth.
- Cost of the wireless service: Some networks offer unlimited usage, others charge by the kilobyte while others charge by length of time connected. Furthermore, users may move in and out of roaming areas while operating a device. A wireless architecture needs to take these issues into consideration in order to optimize network usage and avoid large service bills.
So, How Can the Server Help?
The server plays an important role in wireless device communication, being one of the receivers and senders of information that the device talks to over the network. The content provided to the device needs to be optimized for the limited bandwidth situations. If the chosen protocol is verbose or the server sends a lot of unneeded information to the device, the usability of the device can become compromised. Large amounts of data take longer to download and can be expensive if the wireless service charges by the kilobyte. The server is a participant in providing concise and appropriate units of information to the device.
Another area in which the server participates is the handshaking that must occur when exchanging data between the server and a device. Whenever data is sent from the server to the device, or from the device to the server, some handshaking must take place in order to make sure that the receiving party actually receives the data before the sending party deletes the data or makes some kind of state change as a result of the transmission. If the data transmission is not successful, some type of reconciliation must take place. In some cases, this may mean resending the data. In other cases the problems may be more interesting. For example, suppose that data was sent from the device to the server. The server receives the data and returns an acknowledgement to the device indicating a successful transmission. However, the connection unexpectedly drops before the device actually receives the confirmation. In this case, when the device resends the data, the server must realize that the transmission is a duplicate and handle it accordingly.
In order to optimize how the server communicates with a wireless device, it is desirable to keep the communication to a minimum. If possible, a connection between the server and device should be opened just long enough to exchange some data and then close down. Modems on mobile devices tend to consume a lot of battery power, which is a precious resource for a mobile device. Furthermore, some network providers, such as those operating on CDMA networks, tend to charge by amount of time connected. Keeping the connection open longer than necessary becomes unnecessarily expensive.
Ideally, the data transferred between the device and the server is in a compact format. On this note, XML is not always the most compact format. If the messages that flow between the server and device can be relatively simple, then some type of delimited string or name-value pairs may be more appropriate. However, if the data requires or involves a lot of nested relationships (e.g., customers, their orders and their payment information), XML starts to earn its place.
In keeping transactions short, applications become less vulnerable to spotty network connections. A failure on a short transaction results in resending a small amount of data. A failure on a large transaction results in resending a large amount of data. Not only does the latter consume more network resources, but the reconciliation of a large transmission failure is more complex and increases the potential for state inconsistencies between device and server to develop.
The Burden of Reconciliation
When a network transmission fails, steps must be taken to remedy the problem and make sure that the device and server do not become out of sync. This responsibility could be placed on either the device or the server to fix the problem, or they could share portions of the cleanup tasks. However, it is a good idea to place as much of this responsibility on the server as possible. Servers have far more processing power than mobile devices and can perform these tasks more efficiently. Furthermore, CPU cycles on a mobile device consume battery power; something a server does not need to be concerned about.
The Wireless Challenge
Hopefully by now you are getting an idea of the challenges faced by wireless applications. In the sections that follow, a number of communication models are introduced that help manage these problems. As with most solutions, there are pros and cons with each approach. Therefore, it is important to understand the benefits and weaknesses of each model so the appropriate model can be applied for a given situation.
MVC has become a cornerstone pattern of J2EE development over the last several years. This pattern has surfaced as part of the Sun's Wireless BluePrints in the whitepaper ("Designing Wireless Enterprise Applications Using Java Technology" ). This whitepaper indicates that the device handles the view and the server handles the model and the controller resides on both the device and the server to keep the two in sync. While this pattern does have its place with wireless architectures, it may not be a good fit for many wireless applications. In a world of unreliable network connections, limited bandwidth and various billing rates and plans, relying on a constant network connection may not be desirable or realistic.
In order for a wireless architecture to reliably exchange data and provide services to wireless devices, other models are worth exploring. The following section discusses alternative models where the underlying goal is to exchange data in a manner that does not require a constant network connection. These models focus on bringing the device and server data into sync periodically. Each model contains mechanisms allowing the device and server to recover in the event that the connection fails during a transmission. Furthermore, since a network connection is not required to operate the application, the user interface is never dependent on a server response to display data or interact with the user.
Synchronization models have the explicit goal of exchanging data using a request-response pattern of network communication.
State-Oriented Synchronization Model
Under this model, data is sent from the server to the device, or from the device to the server based on the data coming into a particular state. For example, consider an application that handles to-do lists for employees. Assume that there is a web-based user interface available for employees to create and assign to-do items to each other. A to-do item has four states:
Each state corresponds to how the system will communicate in order to handle the lifecycle of a to-do item. The first state, "Created," indicates that the to-do item has been created (on the server), but it may remain unassigned for a while. However, once the to-do is assigned to an employee the to-do information becomes available to be transmitted to the employee's device. Once on the device, the to-do remains in an "assigned" state until the employee starts the task. Once started, the to-do item moves to the "In-Progress" state. Depending on the business, the server may want to receive an update on this state change so that the server-side user interface can reflect that the employee is working on the task. Once the to-do item is completed, the updated information is sent back to the server, along with the status change.
In order to make all of this happen without loosing data, some handshaking between the device and the server is necessary. Each time the server sends data to the device and visa-versa, the data transmission must be followed by a confirmation. Since the device is responsible for initiating all requests, a request for data involves two HTTP requests. In the first request the device asks for the data. In the second request, the device tells the server whether or not it successfully received and processed the data. The following figure illustrates how the device acquires data from the server.
When data is transmitted in the other direction, from the device to the server, the communication only requires a single request, since the server's reply contains the confirmation. If the transmission is successful, the device may take action on the information sent to the server, such as remove it from its data store. The figure below illustrates sending data from the device to the server, where the device sends data to the server and the server responds with a success or a failure message.
The state-oriented synchronization model fits well into systems that share information based on discrete states where the data is "owned" by either the device or the server based on these states. This model is not a good fit for applications that continuously share or co-own data between the device and server. Nor is this model good a fit when discrete states, which would indicate ownership of information, are not present.
Data-Oriented Synchronization Model
A data-oriented model synchronizes data between the device data repository and the server data repository. One of the biggest advantages to this model is that is can be performed without having to know or understand anything about the business domain. In the previous example the synchronization mechanism requires explicit knowledge of a to-do item and its various states so that the item can be exchanged between the device and the server. Under a data-oriented synchronization model, the device and server repositories are periodically brought into sync, independent of any business processes. To do this, the device and server periodically run a synchronization process. This process sends changes made on the device to the server. The server then records these changes and sends any changes made on the server to the device.
As data is exchanged, handshaking occurs to ensure the data is received on either end. However, since a data-oriented model does not contain knowledge about the business a couple of problems surface. The first problem is data scope. A server must be prepared to handle data synchronization with many devices. How is the scope of data synchronization for a single device managed? In the previous example, a to-do item is sent to an employee's device when the item is assigned. Under a data-oriented model, we need a way to scope the server's data to prevent replicating the entire enterprise onto every device. This can be done by specifying rules that make subsets of the enterprise data available only to specific devices. In the case of the to-do system, there needs to be a mechanism in place that indicates what data is made available to a particular device.
The second problem that surfaces has to do with how synchronization conflicts are handled. Suppose changes were made to the same data elements on both the server and the device. Is one set of changes ignored or lost? Can both sets of changes be merged? Under the state-oriented model this is less of a concern, since either the device or the server has ownership over the data at a given point in time. Using a data-oriented model, rules need to be implemented to resolve these conflicts. At a basic level, rules such as "last write wins", "device wins" or "server wins" can be used as a starting points. However, it is unlikely that these rules will be ideal in all situations. In fact, applying blanket rules such as these can be dangerous. For example, suppose an employee makes changes to to-do item A on their device at 10 AM. Then, at 11 AM, another employee modifies to-do item A from the web interface. At noon, the device and server are synchronized. If we are using a "device wins" scenario, the 11 AM changes are lost. Under a "last write wins" or "server wins" scenario, the 10 AM changes are lost. Although these problems are inherent in any synchronization model, they are most pronounced in data-oriented synchronization. Therefore, it is necessary to have extension points to attach rules so that more complex decisions can be made to resolve these conflicts.
Asynchronous Model (A.K.A Messaging)
Messaging techniques, such as JMS, are well suited for the wireless paradigm. This is because JMS, and other Message-Oriented-Middleware (MOM) data exchange mechanisms, are built around the idea of exchanging data between two systems over an unreliable network. Using asynchronous messaging provides a way for the server to queue up data for the device and for the device to queue up transmissions to the server independent of a physical connection between the two systems.
Under the asynchronous model, where a connection is not always present, a communication channel is opened periodically between the server and the device to allow data to be exchanged. The goal is to empty the queues of data on each system. However, if the window of data exchange is too short to empty the queues, the unsent data remains in the queue until the next transmission window.
In order to guarantee data is sent reliably from one system to another, most messaging systems, such as JMS, implement some kind of handshaking and error recovery processes. If either the server or the device does not receive a certain message, the message stays in the queue and subsequent attempts will be made to resend the data. If the failures reach a threshold, either a timeout or number of attempts, an error handling path may be taken.
Store and Forward
JMS is not required in order to exchange data using asynchronous techniques. They key principle that an asynchronous model employs is often referred to as a store and forward mechanism. Store and forward means that before transmitting a piece of data, a copy of the message is stored in a persistent manner on the sending system. The data remains stored until a confirmation from the receiver indicates that the message was received successfully. Once this confirmation is returned, the sender may delete the persisted data. If no confirmation is returned, or an error is returned, the sender attempts to resend the data. Usually resending is limited to a certain number of attempts or there is a time-based expiration associated with the data to be sent. If these limits are exceeded, the system must deal with the error condition.
Using a store and forward, asynchronous model allows applications to immediately process data for transmission. The application behaves the same whether a connection is present or not. Behind the scenes, the store-forward mechanism is queuing the data and exchanging data in a network-optimized way. This allows the systems to communicate as frequently as necessary, possible or practical given the constraints of the network. The following diagrams illustrate the path of a store-forward model.
Sending a Message
Receiving a Message
Using asynchronous messaging for exchanging data is attractive because of the handshaking that takes place and the ability for an application to queue a message for transmission in the same manner whether or not a connection is present. The down side of this model is that asynchronous transmission may not be feasible for certain applications. For example, if a device submits a request for movie tickets and the user is waiting on the response, the server should respond as soon as possible with the results. In this case, the two systems are not casually exchanging data but are requesting certain things of one another (i.e., sending commands to each other). In this particular example, an asynchronous model is less desirable.
Wireless communication posses different challenges that are not present in browser-based and wire-line client-server applications. There are problems with network reliability, low bandwidth and cost of service that must be addressed. In order to deal with these problems, several models for communication were discussed. Different applications have different needs and therefore it is important to understand what a communication model buys and what needs to be managed. Each of the models discussed focus on moving data between a device and a server while minimizing dependencies on the network and allowing the wireless application to function while disconnected. The server plays an important role in optimizing performance and how wireless applications use network resources.
Sun Microsystem's Wireless Blueprints: http://java.sun.com/blueprints/guidelines/designing_wireless_enterprise_applications/main4.html
Sun Microsystem's J2ME site: http://java.sun.com/j2me/
Sun's wireless developer site: http://wireless.java.sun.com
MicroJava Network: http://www.microjava.com
About the Author
David Hemphill is the Lead Architect for Gearworks, Inc., a company that creates mobile and wireless software for field service industries. David is the co-author of Java 2 Micro Edition from Manning Publications and is a frequent speaker on J2ME at industry conferences. He can be reached at firstname.lastname@example.org.