Networked J2ME Applications


Table of Contents

Introduction
The Problem
A Solution
Pros and Cons of Cell Phones
Why J2ME
Overall Architecture
Technology Stack
Client Technology
The Server Side
Development Tools
Rolling Out The Application
Jar file size
Scalability
In Conclusion
References
Thank You

Introduction

This paper explores the various facets of building a J2ME application. It assumes a working knowledge of Java. The focus is on a MIDP 1.0/CLDC 1.0 application that depends heavily on network access.

I have been working with Java for the past four years, primarily in web application development. For the past year and a half, I have worked on a team developing a J2ME application; most of the information presented here has been gained in that experience.

The Problem

Imagine you are commuting in traffic. There is a long line of cars ahead of you on the interstate; there is a line at the next exit. It looks like a wait either way. Luckily, you subscribe to a traffic congestion service. If you use your cell phone to enter your location, the service can return high congestion areas close to you. Hitting the brakes in frustration, you enter the cross streets just ahead. The traffic service queries a database of current traffic in your city, and informs you that there is congestion on the cross street ahead, making the interstate a better choice. You turn up the radio and leave the other cars on the exit ramp behind.

This problem has some salient characteristics: users need information, and may not be in front of their computer. Data only needs to be queried, not entered, and does not require complex presentation. In addition, the immediacy of access is more important than depth of information.

Other characteristics of this type of problem include: users may be non technical, more than one remote system may be involved, and control over such systems may be distributed--there may be one or more traffic congestion reporting databases in a given city.

To sum up, the problem that this paper will examine is: what is the best way to allow real time, read only access, for remote, possibly non-technical users, to an information system, or set of systems. In this paper, I explain why cell phones clients are a good answer to this type of problem. In addition, I also show how Java 2 Micro Edition (J2ME) is a good platform for such a client. I also outline some of the design choices and technical issues faced when building a J2ME client to access a system like the traffic congestion service.

A Solution

Cell phones are increasingly powerful and available computing platforms. They differ from desktop and higher end mobile clients in a number of ways. Relative to most other computing devices (embedded systems are a notable exception), cell phones have slower persistent storage, less memory, smaller screens, slower processors, and more limited user interfaces.[1] However, while by no means perfect, there are a number of compelling reasons to use cell phones to solve this type of problem.

Pros and Cons of Cell Phones

Advantages of Cell Phones

  • Cellular phones allow access to the Internet in a wider area and at a lower cost than competing technologies. Wi-fi is cheaper and faster, but does not have the broad coverage. Satellite based networks have greater coverage, but can not compete on price (see Iridium).

  • Cell phones are widely available and familiar to most people. Users have or can easily purchase cell phones, and cell phones are more common than other wireless Internet solutions (such as laptops with wireless phone cards or wi-fi). Many people are likely to be comfortable with cell phone applications because of this familiarity.

  • Cell phones are a reasonably sophisticated platform. There are a number of options when deciding how to develop a mobile application, all offering significant functionality.

  • More and more cellular phones will allow an application to retrieve the location of the phone. Such knowledge, combined with GIS data, can allow for unique and valuable applications. Imagine pushing traffic jam locations as a subscriber approached them. (Positing the existence of the back end systems, such a service is possible today, on some higher end phones.)

Of course, cell phones are not a panacea. The technology has limitations.

When not to use cell phones

  • For a complicated user interface, or one where a user needs to input significant amounts of data, cell phones are a poor choice. Since they typically have only the familiar twelve number buttons and two programmable softbuttons, the input interface is limited. Even a small amount of data entry can make a cell phone application tedious.

  • In contrast to the web browser, which has a relatively forgiving and well known interface, some users might not be comfortable running programs on their cell phones. I expect this to change as cell phones become more accepted as a computing platform by normal people.

  • If users need permanent access to remote data, cellular phones are not the right client. Cell phone networks are not renowned for their reliability. (Of course, no wireless technology can promise uninterrupted network access, but others may come closer.)

  • There is a mishmash of competing solutions when it comes to cell phone development. Both the device manufacturers and the cell phone service providers, also known as carriers, play a role in the availability of APIs and platforms. For an application that needs to run uniformly everywhere, cell phones might be too diverse a platform.

It is clear that sometimes cell phones are not the best solution for networked data access, especially if there are extensive connectivity or user interface requirements. However, for a significant set of problems, like the traffic congestion service, they can be a cost effective solution. For read only, real time access to a remote database, cell phones work. They deal with users' remote locations, immediate need to query data and money concerns.[2]

Why J2ME

There are five major cell phone platforms available today: Symbian, Windows Mobile, BREW, WAP and J2ME.[3] Each is worth investigating; depending on the nature of the problem to be solved and the resources and people available, a particular platform may stand out. Frankly, J2ME was chosen to solve my problem not only because it was a good technical fit, but also because the developers were familiar with Java.

Cell phone platform options

  • Symbian is an operating system for cell phones. Later versions of Symbian do support J2ME.[4]

  • Windows Mobile is Microsoft's mobile solution. This platform is aimed at relatively high-end devices and developers with Windows expertise.

  • BREW is a C++ based framework that has support from Verizon. Developers for this platform can rely upon the phone carrier for billing and deployment. However, the certification process required for such support is an obstacle for small companies. IBM has built a JVM for BREW.[5]

  • WAP is an excellent cell phone platform. Some form of it is supported on almost all modern phones; this is a strong selling point. The markup which sits on top of WAP 2.0 is XHTML.[6] Due to that fact, there is very little caching or data validation that can be done on the client.

  • J2ME is a Java based platform for cell phones. It includes everything needed to solve the traffic congestion service problem set: a GUI, persistent data storage, and network access. It is supported by a majority of cell phone carriers in the US, has no licensing issues, and is well documented.

J2ME is not without its warts, including a large number of specifications and technologies. Features that many Java developers consider fundamental (RMI, for example) are implemented at the discretion of the device manufacturer. Early versions of the platform are well supported among newer phones, including less expensive models, but later versions of J2ME are supported by far fewer phones.

One benefit of choosing J2ME is the widespread support for this platform. In addition to the Symbian and BREW support mentioned above, there are implementations for PalmOS and methods of turning J2ME applications into native Blackberry applications.[7] J2ME applications are also relatively easy to deploy initially, especially when compared to BREW applications.

Overall Architecture

In this section I examine the possible architectural choices and some of their benefits.

The J2ME application living on the cell phone will need to communicate with the remote systems. Using the traffic congestion service as an example, there are two alternative designs for this kind of system.

Architectural Options

  • Each cell phone could communicate with every required city traffic system. This solution distributes the networking and processing load onto many clients, but also means that each client needs to know how to communicate with each remote system (assuming the remote systems do not share the exact same protocol and implementation).

  • There could be a single intermediary server which would communicate with each of the cell phones and each of the city traffic systems. This means the intermediate server is a single point of failure (unless made redundant, perhaps via clustering) but also that each client only needs to be able to communicate with one server (via one protocol).

The second solution, illustrated below, is better. By keeping the client simple and pushing complexity to the server, the complexity becomes easier to manage. Mitigating the weaknesses of cell phones--a slow processor, weak user interface, slow and intermittent network access--is a secondary benefit.

The intermediary server architecture. The cell phone communicates via the carrier's network to the intermediary server, which processes requests and dispatches them to other systems, as needed.

Other benefits of the intermediary server architecture

  • Though cell phones are constantly improving, they are still low powered consumer devices. There are certain activities that, while perhaps achievable on a cell phone, are easier done on a server. If the traffic congestion service offloads complicated tasks, such as email notifications to family or friends regarding late arrival or map generation for route finding, to the server, more functionality can be offered without complicating the client.

  • It is possible to cache information retrieved from the city traffic systems at the intermediary server. Therefore, when everyone is stuck at one interchange, the city traffic database is not queried repeatedly, and users will see better performance.

  • For development purposes, the intermediary server offers fewer interactions to manage and debug. Rather than M x N interactions caused by M clients talking to N systems, there are M+N interactions.

  • Authentication and access control become easier; the single server can handle these sometimes complicated tasks. The traffic congestion service can easily make sure users have paid and if there are premium features added, one point of authorization makes controlling access easier.

  • When the protocol to access the city traffic systems change there is no need to track down and persuade users to upgrade the application on their cell phone; instead the intermediary server can be easily upgraded. Clients can use whatever protocol is best for communicating over the wireless network, rather than being forced to understand the (perhaps different) protocols of the remote systems.

However, an intermediary server means more testing and more code to maintain, and if that server fails, the application is inaccessible. However, the alternative architecture, each client talking to each remote system, is a protocol management nightmare, requiring complex J2ME clients.

Technology Stack

In this section I examine the technologies used to roll out a network application based on the J2ME platform.

Client Technology

Before examining implementation details of a networked J2ME client, it is worth exploring the basics of the J2ME platform and the applications written for it, known as midlets.

Basics of J2ME

Pieces of the J2ME platform

  • CLDC stands for Connected Limited Device Configuration. In J2ME, a “configuration specification defines the minimum required complement of Java technology components and libraries for small connected devices[8], including almost all of the supported classes in the java.lang package. Most cell phones will use this configuration. (There is another configuration, the Connected Device Configuration, for higher end devices.) At the time of writing, there are two versions of the CLDC: 1.0 and 1.1.

  • MIDP stands for Mobile Information Device Profile. This is a higher level API with which most developers will interact, and includes classes for the user interface, persistent data storage and other functionality.[9] Currently, there are two versions of this API: 1.0 and 2.0.

  • Optional packages are a crucial part of the J2ME platform, even though they seem to lack the requisite acronym. There is functionality that has been standardized by the JCP and that is a defined part of the J2ME platform: APIs such as JDBC, RMI and location based services (LBS). However, it may not be appropriate to have this functionality on every device. Therefore, it is not part of a profile or configuration, the implementation of which are mandatory. For example, if a device does not have the processor speed to support RMI marshalling and unmarshalling, the manufacturer may choose not to implement that package. But if they do, they must conform to the specification. Optional packages must be implemented by the phone manufacturer; they are not simple libraries that a developer can include with his midlet.

  • The J2ME platform on a given device consists of a device configuration (for example, CLDC) and a device profile (for example, MIDP), plus optional packages. In general, the configuration sits below the profile, and different versions of each may be paired. The configuration handles lower level interactions with the device, whereas the profile handles user interface and other higher level abstractions. Separating these allows them to evolve at different paces.

    The J2ME API intersects with J2SE. Depending on the versions of the profile and configuration chosen, the java.io, java.lang, and java.util packages will be present (the red area below). In addition, there are some J2ME specific classes, in the javax.microedition package (the green area below). This package includes sub-packages which hold user interface, lifecycle, I/O and other J2ME specific classes.

    Intersection between J2SE and J2ME platforms

    If a class is present in both J2ME and J2SE, there is an attempt to make the classes compatible. However, it is an attempt, not a promise. From section 6.1.2 of the CLDC 1.0a spec: “The majority of the libraries included in CLDC are a subset of the larger Java editions (J2SE and J2EE) to ensure upward compatibility and portability of applications. While upward compatibility is a very desirable goal, J2SE and J2EE libraries have strong internal dependencies that make subsetting of them difficult in important areas such as security, input/output, user interface definition, networking and storage. These dependencies are a natural consequence of design evolution and reuse that has taken place during the development of Java libraries over time. Unfortunately, these dependencies make it very difficult to take just one part of the libraries without including several others. For this reason, we have redesigned some of the libraries, especially in the areas of networking and I/O.

    This “subsetting” is evident in many places. The String class in JDK 1.3 has 47 non deprecated methods, not including those inherited from Object, including compareToIgnoreCase and intern. These methods are not among the 34 included in the CLDC 1.0 implementation of the String class. And when compared with the more feature-laden JDK 1.4 String class, J2ME omits many more methods.

    Entire classes are missing (the white area area above), including such useful classes as java.util.Collections and java.util.Properties. Most of the differences are outlined in section 5 of the CLDC 1.0a specification.

    Sometimes the differences are subtler. Just as in J2SE, the Thread class should not be stopped via the stop method. Where the J2SE Thread class has a deprecated stop() method[10], J2ME simply does not have the stop method[11].

    Note that differences outlined above are configuration and profile dependent. Differences in the library classes are the obvious incompatibilities, but there are also language feature differences between J2ME and J2SE. In J2ME, JNI is disallowed and asserts are not supported. I was unable to track down exactly what version of the java language J2ME supports, but my experience has been that it supports the language features of JDK 1.3 and has a library similar to JDK 1.1 (Vectors and Hashtables). The bytecode is similar to that of J2SE, with a few differences.[12] In short, J2ME is similar enough to J2SE to allow use of many of the same tools, and a developer competent in one can pick up the other quickly.

  • There are two files needed for a J2ME application. One is the jar file, the typical zipped archive of classes and resources. The other is the jad file (see Example 1, “Sample jad File”), which is very similar in purpose, if not in format, to the web.xml descriptor used in java web applications. The jad file contains information about the midlet which is used by the phone on installation.

    Example 1. Sample jad File

    1 MIDlet-1: SampleMidlet, , com.foo.SampleMidlet
    2 MIDlet-Jar-Size: 74274
    3 MIDlet-Jar-URL: SampleMidlet.jar
    4 MIDlet-Name: SampleMidlet
    5 MIDlet-Vendor: SampleMidletVendor
    6 MIDlet-Version: 1.0
    7 MicroEdition-Configuration: CLDC-1.0
    8 MicroEdition-Profile: MIDP-1.0
    

    (Line numbers are not part of the file.) There must be a entry similar to line 1 for each midlet in the jar file, including the name of the midlet, an optional icon filename, and the full name of the midlet class (which must extend javax.microedition.midlet.MIDlet). The jar file listed on line 3 must be the size listed on line 2. For this reason, jad files are often generated. Lines 4 and 5 are shown during the application installation process. Line 6 is used for versioning during the installation process--some phones prompt the user during midlet install if there exists on the phone a midlet of the same name and version number. Lines 7 and 8 indicate the versions of the configuration and profile that this application requires.

Client Specifics

Applications aiming for a wide user base of consumers, such as the traffic congestion service, would be best served by supporting the CLDC 1.0 and MIDP 1.0 specifications because these are the earliest mature specifications; both were released in 2000. They are also the most widely supported of the J2ME specifications. Different problem sets may require different API choices, though. For example, an application may need to perform floating point calculations or access the location of the phone. In such cases, later specifications may be worth looking at: CLDC 1.1 supports java.lang.Float[13] and has support for LBS.

In the next sections, I will explore some of the basic ingredients of a J2ME application, including user interface, navigation, and networking.

User Interface

J2ME user interface development is similar to Swing development. Applications are structured around a series of screens. The main user interface elements are strings and images to convey information, and text input fields and choice groups (similar to radio buttons) to gather information. All of these elements are placed on a Form, a class similar to JPanel. Unlike Swing, where there are several different layout managers, in MIDP, there is exactly one. This layout adds elements to the screen, each in their own row. If absolute control over drawing the screen is important, the Canvas and Graphics classes, which according to the MIDP 1.0 specification, are “designed for applications that need precise placement and control of graphic elements and access to low-level input events.

Since the user interface is limited, it is a good idea to ease information entry whenever possible. Do not use a text field, which forces users to enter letters and numbers using the keypad, when a choice group, which lets users select one option among many, will work. Do not present a choice group when there is only one valid choice. Specify constraints for text fields when possible.[14] Do not make the screens too large, as then users will have to scroll. However, balance this against the number of screens needed to collect data and try to attain a happy medium. Provide sane defaults whenever possible--commonly selected options or example values can make the application easier to use. Find out what parts of the application are most important to the user and make them prominent.

Softbuttons with multiple actions associated

A typical cell phone has two soft buttons, used to handle high level actions (as opposed to low level events like keypad button releases). More than one action can be associated with a softbutton, but doing so means a more complex navigation, as shown above. Use softbuttons wisely--minimize the number of actions associated with them.

J2ME user interface issues are similar to those of other software environments, but requirements are more stringent. The MIDP 1.0 spec suggests a screen size of at least 96x54 pixels, which does not give application developers much room for mistakes. In addition, the “consumer device” nature of most cell phones means that usability expectations of installed applications are high--unlike a computer, where training is the expectation, I feel that most people expect to pick up a cell phone and be able to use installed programs.

Application Navigation

In order to flow from one screen to another and enable users to return to previous states in the application, a stack can be used. Whenever a user chooses to go to a different state, the current form is pushed on to the stack. If the user returns to the previous state, the application pops the stack and brings back the previous form. This design is Model 1. Each screen knows the transitions available to the user. This architecture is a simple solution, easy to understand, and keeps the client small. Having a central configuration and controller, like many web frameworks, is overkill for a typical J2ME application.

Networking

Since applications like the traffic congestion application depend so heavily on real time data access, networking is important. Networking access in J2ME requires understanding threads. As in Swing, in J2ME there is a system thread responsible for redrawing the screen. This thread should not block for any reason, including waiting for I/O or network access. In some emulators, the blocking behavior is not emulated correctly, but the flaw is apparent when an application is running on a real phone: the phone locks up. Why? Many phones require user permission for an application to access the network--and if the system thread is busy trying to access said network, it cannot respond to the user's permission granting; deadlock ensues.

Separate threads access the network but what will the communication between the cell phone and the intermediary server look like?

Options for Data Transfer Between Server and Client

  • A proprietary scheme over sockets is the fastest method of data transfer, but will be brittle if data requirements change. In addition, MIDP 1.0/CLDC 1.0 do not support sockets.

  • A proprietary scheme, such as fixed width fields or key value pairs, over HTTP is another option. HTTP is supported, but such a scheme will, again, be brittle in the face of change.

  • RMI is the best of all worlds--since the application is so dependent on network access anyway, why not have it be transparent and just ship objects back and forth between the server and the client? Unfortunately, RMI is an optional package.[15] Requiring RMI will thus limit the number of devices on which the application can run.

  • SOAP is a great option. However, it can be a bit heavyweight at times[16].

  • XML over HTTP is easy to build, can be used for different clients fairly trivially, can be debugged in a browser, and can leverage all of the tools available for testing websites.

In the end, a custom XML format was chosen. When processing the XML, a third party library was used[17], and the strings were decoded into java objects. These java objects were then passed on to the user interface. Javabeans with synchronized getters and setters and the producer consumer pattern were used to ensure that the user interface did not display information until it had been retrieved from the network. Below is s a sample network interaction explained in the context of the traffic congestion service.

Sequence Diagram for Retrieving And Displaying Information From the Network

First, the user enters an address. The User Input Form object creates the Wait object, which displays a 'Waiting for Data' message to the user. The Wait object starts a new thread, the Logic object, that is responsible for retrieving and processing the data, and passes itself to the Logic object as a reference. The Wait object is pushed onto the display stack maintained by the Controller object, by the User Input Form, which then causes the Wait object to be drawn on the screen. Meanwhile, in the Logic object, network access is deferred to yet another thread, the Network Worker. The Logic object communicates with the Network Worker through one or more Transfer objects, which are simply beans with synchronized get and set methods to which both the Logic and Network Worker objects have references. The Network Worker connects to the network, and receives an XML input stream containing information regarding the traffic jams around the address the user entered, which it puts in the Transfer object (see Example 2, “Network Connection Code” for code). The Logic object has been waiting for this input stream, and processes it by parsing the XML into domain objects (see Example 3, “XML Parsing Code” for code). These objects are then passed back to the Wait state, which then creates a new Form object, passing the retrieved data to the new Form in its constructor. Then the Wait object passes control to the new Form by pushing it onto the stack. This then causes the Form to be drawn on the device, displaying whatever data has been retrieved from the network and perhaps prompting the user for more data.

Example 2. Network Connection Code

1   hc = (HttpConnection) Connector.open(urlst);
2   if (null != sessionCookie) {
3      hc.setRequestProperty("cookie", sessionCookie);
4   }
5   if (post) {
6      hc.setRequestMethod(HttpConnection.POST);
7      hc.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
8      hc.setRequestProperty("Content-Length", Integer.toString(message.length()));
9      out=hc.openOutputStream();
10     if (null != out){
11        out.write(message.getBytes());
12     }else{
13        Log.logError("couldn't write post data to output stream");
14     }
15  } else {
16     hc.setRequestMethod(HttpConnection.GET);
17  }
18  hc.setRequestProperty("Connection", "close");
19  is = hc.openInputStream();
20  t1.setPayload(is);

This is a section of the Network Worker object's run() method. It opens up a network connection on line 1, attaches a cookie to the request on lines 2-4, sets appropriate properties depending on whether the HTTP request is a POST or a GET on lines 5-18, and retrieves the input stream containing the server's response on line 19. The input stream is then passed to a transfer object on line 20.

Example 3. XML Parsing Code

1   while ((event = parser.read()).getType() != Xml.END_DOCUMENT) {
2      int type = event.getType();
3      if ( (type == Xml.START_TAG) && (event.getName().equals("INTERSECTION"))) {
4          String name = event.getName();
5          IdDescriptionPair intersection = new IdDescriptionPair();
6          intersection.id = event.getValue("code");
7          intersection.desc = event.getValue("description");
8          returnVector.addElement(intersection);
9      }
10  }

XML input is parsed by checking for start tags on line 3. The scenario here is that the traffic service application does not have enough information based on the address entered, so a set of suggested intersections is returned. Intersection data, as represented by the INTERSECTION tag, has two attributes, code and description. The values of those attributes are placed into a domain value object on lines 6 and 7. There will likely be more than one, so a Vector is used on line 8 to hold all of them for iteration and display on the screen.

Networking code has some phone specific peculiarities. In particular, the header handling has been different between phones. On some Motorola phones, when there is more than one cookie, the later ones are not seen. In addition, handling cancel events means communicating back to the network accessing thread; this communication can only happen at certain times (not when the thread is blocking on network access). Also, most phones ask users if an application can access the network, since doing so costs the user money. If the user says no, a security exception is thrown, and must be handled by the application. These issues, as well as the deadlock issue mentioned above, make it clear that testing on as many real phones and emulators as possible helps smoke out non standard behavior that will adversely affect the user experience.

Cell phone applications exhibit decent network performance. The user experience has depended greatly upon the cell phone network--some carriers simply have higher data transfer rates than others. This is not a rigorous analysis, but while demoing applications, I have never seen it take more than ten seconds or so to download ten KB of information from the network.

Security

Mobile phones are lost, stolen or misplaced more easily than laptops. Anything that needs to be secure should not be on a cell phone; if data needs to be secure and must reside on the cell phone, look at encrypting it. In the case of the traffic congestion client, sensitive data, including authentication tokens to remote databases, could be kept on the server.

Permanent storage

Cell phones have static memory which J2ME exposes via the recordstore API, using classes in the javax.microedition.rms package. Recordstores are an array of byte arrays. The store is easier to work with if treated as a persistent hashtable.[18]

Images that are downloaded from the network and then displayed can be cached in the recordstore for a performance increase. However, doing so requires storing the raw byte[] array before displaying the image. Such a a byte[] array can be easily turned into an javax.microedition.lcdui.Image object, displayable on a screen. However, there is no way to turn an Image object into a byte[] array after it has been created.

The Server Side

The server that the J2ME application will communicate with need not be complex. A typical open source J2EE application will suffice: Apache, fronting a tomcat servlet engine, with struts as the MVC framework, and using mysql as a datastore. I am only going to address a few points where the nature of the J2ME client influences the intermediary server.

The struts framework can be used in two separate scenarios: to build a typical web application, allowing users to sign up and pay for the traffic congestion service as well as other account management activities best done with a browser, and also to generate XML for the cell phone application. In the second case, not all the features of struts need to be used--client side validation and action forms are both superfluous, for example. Since all that is communicated between the the cell phone and the server application are sets of XML messages, the main benefit of the action form, validation and error messages, is not useful. When transmitting binary data such as images, a simple custom servlet streamed the data as a java.io.ByteArrayOutputStream over HTTP.[19]

JSPs can be used to generate XML. Since WAP supports a subset of XHTML, adding another view layer to the server application is easy. (This took about 6 hours for our application and not a single Java class was touched.) However, limitations of WAP mean advanced features are not available to the WAP browser client--in particular, information collection for a given request can (and should) be spread over multiple screens with the rich client, while it must be gathered on one screen with the WAP browser.

In order to generate and manipulate images, JAI was used. It is poorly documented; the main form of documentation, javadoc, does not provide much help for beginners, and the tutorial is a few versions behind. However, the mailing list is very useful. The JAI library can be used to transform GIFs and JPGs into PNGs.[20] JAI can be used to flatten images from 24 to 8 bit color. Since images are shown on cell phone displays of such small resolution, trading color depth for download speed can be acceptable.

Development Tools

J2ME development is similar to J2EE and J2SE development in many ways. Developers write classes that fit within frameworks like Swing and struts. However, due to the limitations of the cell phone platform, there are several J2ME specific tools.

Useful J2ME tools

  • J2ME emulators mock up the J2ME runtime environment on a desktop PC, allowing development to occur on a device that has more memory, a faster network connection, and a keyboard. Emulators are available from many sources: Sun, IBM, most device manufacturers and even a few carriers. The Sun Wireless Tool Kit (WTK) has an excellent emulator. IBM's WebSphere Device Developer (WSDD) has an emulator integrated with an IDE; this made for a great development environment, but the version I used did not handle the network threading deadlock appropriately and cost money. Both of these emulators support Windows and Linux. However, most cell phone emulators only run on Windows. Other emulators can be downloaded from device manufacturers' or carriers' websites.

    Be aware that when developing using emulators, the advantages gained can also lead to user experience issues: for example, it may make sense to download a logo for the traffic service every time if a fast reliable network connection is available, but this is not the case if the application is using the cell phone network, which is neither fast nor reliable. Be aware of such non functional problems and test on real phones as often as possible.

  • Building midlets take more steps than building a normal web or java application, including preverification of classes[21] and jad file generation. WSDD and WTK can take care of the additional steps, but then development has to take place in that context. antenna, on the other hand, is a set of ant tasks that leverage existing WTK classes to enable command line midlet builds. In addition, antenna also provides the ability to build midlets for other platforms and create automated builds.

  • The size of the application jar file can be important, if for no other reason than application download time. Obfuscators are java programs that can be used with any class file; they twiddle with byte code and rename classes and variables to make decompilation more difficult. As a happy side effect, however, they also decrease the size of class files. proguard is one such obfuscater. Easy to use and feature rich, it also integrates with the WTK. Jode has also been recommended, but I found it difficult to use.

Rolling Out The Application

Actually rolling out a J2ME application to cell phones is easy. Buy a J2ME capable phone; there are lists of compatible phones on the web. [22] Get a data plan--4MB a month has been ample for me. Place the jad and jar files on a web server. Modify the web server's mime types to assign the correct content types to the .jad and .jar extensions:

Example 4. Addition to web server mime types for Apache

...
application/java-archive                jar
text/vnd.sun.j2me.app-descriptor        jad
...

Every phone capable of running a midlet will have a browser. To install, download the jad file; the midlet support infrastructure asks the user for permission to install the application, deals with versioning issues, and downloads and actually installs the application. In some cases, browsing directly to the jad file triggers the installation process; however, in one or two cases bizarre behavior prevented installation in this manner. The solution is to browse to an XHTML file that has a link to the jad file; such an XHTML document need not be complex (see Example 5, “XHTML File Used to Install a Midlet”).

Example 5. XHTML File Used to Install a Midlet

<a href='file.jad'>Application</a>

For an application such as the traffic congestion service, licensing and piracy are not huge issues. This is the case for most networking midlets, since the value comes from remote data delivered at the appropriate time, rather than the application itself. Delivery takes place after authentication, so if a user is not recognized or has not paid for the service, access can be easily denied.

Some aspects of J2ME deployments are not in the developer's control. For example, one source of frustration for me has been Verizon. This carrier, the largest in the USA, simply does not support J2ME.[23] Optional package implementation is similar--if a device manufacturer has not implemented an API needed, the application simply cannot run on that device. Contrast this with the J2EE world, where the server is under the application developer's control, or at least influence. In addition, J2EE's typical delivered product, HTML, has a fairly standard feature set; with J2ME, clients differ in their capabilities.

Jar file size

In addition to speedy download as a reason to decrease jar file size, some phones, particularly inexpensive Nokia models, simply do not accept jar files larger than 64KB. Obfuscation tools such as proguard help, but even with obfuscation and elimination of unused classes, jar files might be too large. Other means of decreasing the size include design compromises and removing logging statements. Often, value objects on the client side have, in good javabeans style, get and set methods. To decrease the size of the class files, these can be replaced by public variables (see lines 6 and 7 of Example 3, “XML Parsing Code”). Commenting out logging statements, which generate a large number of String objects, decreases the size of the jar file significantly, as commented out Strings are not included in the class files.

This optimization experience was something new to the development team. After all, in the world of J2SE and J2EE, there are a different set of constraints--programmer time, database access, execution speed. How many developers ever really pay attention to the size of their class files?

Scalability

If an application has not been widely rolled out, scalability is difficult to ascertain. The traffic congestion service does have usage scenarios: a user will login, enter some data, and receive an answer. Perhaps they will check for traffic jams once or twice during the commute, but most users will not be using the service all day. Therefore, the application should be built to handle spikes during rush hours. One tool that can be used to gain an idea of performance is The Grinder. Of course, requests from a PC or set of PCs are not entirely reliable emulations of the real usage scenarios, but it is a starting point.

One concern is, though the MIDP 1.0 profile supports HTTP 1.1,[24] clients with slow network connections require the server to have a larger number of sockets open for a given number of clients over a specified period of time, when compared to speedier clients. Ten clients that each take ten seconds to read a given amount of data, starting in one second intervals, will require a maximum of ten sockets, whereas ten clients that each take one second to read the same amount of data, starting in one second intervals, will require one socket. I am not sure at what point such behavior will have a negative effect on performance, but it should be considered when thinking of the number of supportable clients.

In Conclusion

In this paper, I have examined the kind of problems that rich client applications residing on cell phones solve. Cell phone platforms were examined, and I explained why J2ME was a good choice for an application like the traffic congestion service, where data was needed quickly while away from the desktop computer and little user data entry was required. I also covered the basics of J2ME and discussed some of the quirks that I have encountered, including device discrepancies. Even in the J2ME world, it is important to realize that, while MIDP 1.0/CLDC 1.0 gives a firm base from which to build, APIs for carriers and device makers will vary. I also looked at the different types of client/server solutions available to solve the problem, and some of the tools that made building midlets easier.

For many problems, J2ME can be a good solution with a low barrier to entry. As more and more phones can support more and more complex functionality, J2ME will continue to grow in promise. The variety of functionality available now reminds me of the web browser market in the mid 1990s; exciting things are in the works, even if many of the bugs have not been shaken out yet.

References

Thank You

Thanks to Brian Rook, who brought me into his J2ME project.

Much thanks to my reviewers, who caught many mistakes and made some great suggestions. Any errors still present are of course my responsibility.

  • Dion Almaer
  • Bryan Buus
  • Aprille Jordan
  • Michael Yuan
  • Corey Snipes
  • Andy Pai
  • Pat Myers
  • Jeff Barry
  • Mike Mahon


[1] For more information on the constraints of a typical cell phone, see section 2.1.1 of the MIDP 1.0a specification and 2.2.1 of the CLDC 1.0a specification.

[2] This is a great example of nearlynet.

[3] For more information on these five platforms, see the 'Mobile Operating Systems' section of Chapter Seven of Mobile and Wireless Design Essentials.

[5] See http://www-106.ibm.com/developerworks/library/wi-tip21.html for more. Such a bridge will allow J2ME applications to be deployed on BREW phones. I'm unsure when this bridge is scheduled to come out.

[6] Actually, it is a subset of XHTML, XHTML MP. See this page for more information.

[7] See page 12 of the Creating MIDP Applications for BlackBerry located in the Blackberry Developer Site.

[8] From section 1 of the CLDC 1.0a specification.

[9] See section 2.2 of the MIDP 1.0a specification for an outline of these functional areas.

[11] See the javadoc in the CLDC 1.0a specification bundle. Confusingly, code that called Thread.stop() still compiled and ran for me, using Sun's WTK. Additionally, here is an article about using threads in J2ME applications.

[12] See section 5.1 and 5.4.2 of the CLDC 1.0a specification for more information on the dissimilarities.

[13] In this specific case, floating point support for CLDC 1.0 does exist; there appear to be licensing restrictions.

[14] For more information on the constraints, see the javadoc forjavax.microedition.lcdui.TextField.

[15] This optional packaged reached 'Final Release' in June, 2002. For more information, see its JCP page.

[16] Frankly, all the network layer is doing in our application is connecting to the network, passing some request parameters, receiving an XML response and turning that into a java object which represents the domain (the nearest traffic jam, etc). The latter two pieces would fit very well with SOAP, but by the time it was considered, the XML infrastructure was built and working.

[17] The excellent kxml library.

[18] As outlined in Wireless Java: Developing with J2ME, by Jonathan Knudsen.

[20] PNG is the only format guaranteed to be supported by MIDP 1.0. On page 237 of the MIDP 1.0a specification: “Implementations are required to support images stored in the PNG (Portable Network Graphics) format, version 1.0.

[21] For more information on preverification of classes, see section 5.3.1.1 of the CLDC 1.0a specification.

[22] http://jal.sun.com/webapps/device/device is one such list of phones.

[23] Visiting the Verizon developer website, there is no mention of J2ME or Java. In addition, there are other other websites which outline the capabilities of various carriers.

[24] See section 6.2 of the MIDP 1.0a specification.