Developing Java for small spaces
FOR YEARS NOW, Sun has promised the Java mantra: "Write once, run anywhere." The reality of developing Java applications for small spaces has tarnished that dream. Developing Java applications to run in cell phones, pagers, automobiles, and industrial devices has returned Java to its original target environmentsmall spaces. But these small spaces require equally small virtual machines (VMs) that are functionally limited. Desktop developers attempting to write Java applications for these devices must adjust their expectations and programming style to fit the space.
This installment of "Java for Small Spaces" is the first in a series, and will introduce some of the issues related to developing Java applications for small memory and processor-limited devices, while familiarizing you with a few of the many small Java environments. The pri-mary focus of this column will be to introduce you to the Java small space environment and the particular pitfalls awaiting the traditional application developer in the traditionally embedded developer world. In future columns, we'll examine some of these embedded development environments in detail.
So Many Environments, So Little Compatibility
There are a growing number of players in the Java for small spaces market. Sun has partnered with a number of companies to develop new J2ME classes called profiles and configurations that describe useful APIs. Sun has also developed a couple of JVMs for sub-PC environments. Motorola (partnering with Sun) has developed a Java KVM and device emulation environment for its iDEN mobile phone. IBM has developed an independent implementation of the JVM named J9, supporting it with the sophisticated, integrated development environment, Visual- Age Micro Edition. Chip manufacturers are also wading into the embedded Java fray with small boards and single chip processors containing storage and a JVM. Manufacturers, such as Dallas Semiconductor (DalSemi) and stalwarts like Zilog, are creating useful products for software developers who were once excluded from what was once a traditionally firmware-only world.
Each of these embedded development platforms provides different benefits while imposing certain limitations. Let's first make the distinction between the terms "platform" and "configuration." We'll define the term platform as the hardware (processor, memory, peripherals) that the VM executes on. A configuration is a specific VM and its associated Java APIs and libraries. Device manufacturers often produce a configuration tied to their platform.
Each of the companies mentioned above produces JVMs. The VMs are designed either for third-party platforms or internally produced platforms. For example, DalSemi has created the Tiny InterNet Interface (TINI) Java embedded computer. DalSemi based its Java VM on Sun's JDK 1.1 API with some restrictions. DalSemi develops its Java VM and class libraries internally. Thus, DalSemi's focus is on its own Java products (TINI and iButton). On the other hand, IBM produces the J9 VM, which runs on a number of different platforms produced both internally and by third parties. IBM has created a set of three configurations for its VM based on the resources available in the embedded device. The jclXtr configuration starts small at ~100K. From there, the jclCore configuration grows in features and resource usage to ~300K. Finally, the jclMax configuration gives the developer a full-featured set of classes at the cost of ~2MB. Because of diminishing resources within the target platform, IBM provides different configurations to work with the broadest range of platforms.
Then there's Sun. Since Sun is in effect the father of Java, it has taken on the role of Java standards bearer. Sun has used its developer community process to establish a set of standards for these small spaces based on its J2ME specifications. For example, Sun defines its J2ME environment with a set of device models called profiles and configurations. Profiles define behavioral APIs that are, in theory, independent of a particular hardware configuration. But as we'll see in future columns, profiles and configurations can be somewhat co-dependent and confusing.
|Building the UITest.java example.
|Assuming you have downloaded Sun's J2ME_CLDC_FCS into the directory c:\j2me_cldc-1_0, the following build file should build the UITest.java example.
Build the example:
Preverify the example:
javac -g:none -deprecation -d
Make a Palm application:
..\..\bin\preverify -classpath \
Install the resulting .prc file into the PalmOS emulator.
java palm.database.MakePalmApp -v -
version "1.0" -bootclasspath \j2me_cldc-
One item that is not confusing is the distinction in J2ME between "Personal Profile" devices and all others. Personal Profile devices use the JVM configuration, as opposed to the KVM configuration. The Personal Profile with the JVM configuration looks and acts pretty much like a full-blooded JVM. The reference platform Windows CE (WINCE) uses a 2.2MB executable. I don't know many firmware developers who would call 2.2MB a small space! In contrast, the J2ME Mobile Information Device Profile (MIDP) works with the KVM configuration and operates in 128K512K of memory with a very restricted set of supported classes. At the small end of the Sun J2ME configuration spectrum is the JavaCard, API, and VM. JavaCard supports devices with as little as 6K of RAM. Now we're talking small!
The most notable limitation shared by all of the small environments we'll look at (except J2ME Personal Profile) is that AWT/Swing and most I/O-related classes are missing. Each environment and device type provides different classes for user interaction and persistence specific to a device platform. Therefore, an application written to the API of one environment or device type will require modification to run elsewhere.
If you're a traditional application software developer, you probably don't have much experience developing for small spaces. Odds are good that you virtually ignore your execution environment. To be successful in small spaces, you need to consider the abilities and limitations as primary factors in your design. You must learn to think like a firmware developer. When developing for small spaces, you will be struck immediately by some limitations:
- Embedded device processors are usually orders of magnitude slower than desktop or server systems.
- Due to limited resources, standard Java classes you may consider part of the language base are omitted.
- Size matters.
These are limitations firmware developers live with every day. If you have a Java application you think would be useful in a small space, consider the environment. How much character data entry is required? Can your application's navigation be simplified to short menu selections without too many levels of drill-down? Does the application need to display more than a few words at any given time? Does your application require Java Collections classes, Reflection, floats/doubles, or any other of a dozen missing packages and classes considered to be "base" functionality?
You must factor the environment into the design of your application and not expect to write it once and run it anywhere!
The theory is that there will be many devices that support a particular profile. In theory, you will write your application to conform to a profile/configuration and it will port across like devices. The benefit of the profile is to define a predictable execution environment across multiple devices. The reality, however, may be quite different.
There are many places to start. If you just want to see a Java application run on a ubiquitous device such as a Palm Pilot, use Java class packages available from Sun or IBM to get started.
Download the KVM, .prc files, and a sample application or two from Sun technology evangelist Bill Day's Web site. Or download IBM's VisualAge Micro Edition, v. 1.3, which also supports the PalmOS and has good sample applications. If you are more than simply curious, you must decide on a couple of issues. What problem are you trying to solve, and which platforms will you target? The solution must match the platform.
- Platform Option 1: If you want to develop the next killer application for a phone to communicate with a back-end server, then you need to develop under a KVM configuration with the MIDP profile. You need to obtain the KVM development kit and emulation environment from Sun.
- Platform Option 2: If you want to develop an industrial control application running on top of a real-time OS, take a look at IBM's VisualAge Micro Edition 1.3 with J9 VM running on top of Neutrino RTOS. IBM's VisualAge Micro Edition 1.3 also offers a remote debugger and an integrated development environment to ease the process. Keep in mind, Neutrino is not free and the J9 running on top of Neutrino must be licensed.
- Platform Option 3: If you want to develop your very own device with blinking lights, buttons, and a small display, check out TINI from DalSemi with its programmer-friendly 1-Wire Interface. The TINI is a 72pin SIMM form factor chipset with a Java-enabled processor containing 512K1MB of memory. TINI can run a Web server hosting Java servlets communicating with connected hardware via its serial and 1-Wire Interface. The 1-Wire Interface lets you programmatically read and set hardware switches through your embedded Java application.
Dealing With a Small GUI
To begin, let's look at a common problem for a first-time Java developer to the Palm Pilot platform. Recall that the J2ME/KVM configuration does not have intrinsic support for GUI on a device. In non-PC devices, the user interface is unpredictable, so each platform will have its own profile defining UI and persistence. In the case of the PalmOS, Sun has defined a package (not officially a profile) called Kjava. This is for demonstration of the KVM on PalmOS as a reference platform. Using CLDC Kjava graphic classes, you see a good assortment of GUI widgets, buttons, lists, sliders, textFields, etc. But interaction with these are very different from what you may be used to in AWT or SWING. Instead of having an event handler for each GUI object, you have a single handler for all events. Every Java application under PalmOS is a subclass of Spotlet. By default, your Spotlet will receive "pen" and "key" events along with some others. You must override any events in your subclass of Spotlet that you wish to capture.
The only tricky bit involves maintaining the GUI state. You will maintain the state of which textFields have focus and explicitly loseFocus and setFocus when moving between fields. You must also determine which fields or buttons receive the penDown events based on the bounding box of the widget. In other words, you use a laborious if/then/else structure to determine which widget, if any, received the penDown/penUp.
Listing 1 shows the penDown handler for a UITest. This simple display contains two text fields, two buttons, and a slider. Notice when one text field receives the focus, we must manually determine which field formerly had focus. (The complete source code is available in the code section.) To build the UITest.java example for this article see the sidebar on page 60.
Developing a Java application for a small device isn't as simple as copying your favorite Java application to a cell phone. On the positive side, you can take advantage of your language experience to develop new applications specific to a particular small environment. Also for the first time, software developers can write code in devices that have traditionally been the sole domain of firmware developers.
In future columns, we'll look at the details of developing in each of the small space environments. Until then, play around with J2ME or VAME demos running on a Palm Pilot. You'll enjoy seeing how much you can do with so little computing power!