Monday, August 6, 2007

Java Programming on the Sharp Zaurus

The Sharp Zaurus (SL-5000) is a geek's dream device. A color, touch-sensitive screen, a tiny QWERTY keyboard, and the Linux operating system are crammed into a palm-sized package. A CF card slot allows for an 802.11 or Bluetooth wireless networking card. Best of all, the Zaurus can run Java applications. The Zaurus was on sale at the 2002 JavaOne Conference for a steep discount. If you've picked one up, you might be wondering what you can do with the Java platform on the Zaurus.

This article describes how to program your Zaurus using the Java programming language. It provides a quick demonstration, then discusses the details of the Personal Profile and its close cousin, the PersonalJava platform. The article concludes by showing how to package a Java application for the Zaurus.

Cheap Thrills

Talk is cheap. This section describes how you can get some Java code running on your Zaurus quickly. Later on, I'll discuss the details.

I assume you have a Java compiler handy on your desktop computer. If you don't, you should skip this section and read the rest of the article before you start writing code. Copy the following source code into a text editor and save it as HelloPP.java. (You may download the file if you wish.)

import java.awt.*;
import java.awt.event.*;

public class HelloPP
extends Canvas {
public void paint(Graphics g) {
Dimension d = getSize();
int cx = d.width / 2;
int cy = d.height / 2;
for (int x = 0; x < d.width; x++) {
if (x % 2 == 0) g.setColor(Color.black);
else g.setColor(Color.white);
g.drawLine(cx, cy, x, 0);
g.drawLine(cx, cy, x, d.height);
}
for (int y = 0; y < d.height; y++) {
if (y % 2 == 0) g.setColor(Color.black);
else g.setColor(Color.white);
g.drawLine(cx, cy, 0, y);
g.drawLine(cx, cy, d.width, y);
}
}

public static void main(String[] args) {
final Frame f = new Frame("HelloPP");
Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
f.setLocation(0, 0);
f.setSize(d.width, d.height);
Component c = new HelloPP();
f.add(c);
f.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent we) {
f.dispose();
System.exit(0);
}
});
f.setVisible(true);
}
}

Now compile this source code with this command:

javac HelloPP.java

If you are using J2SDK 1.4.0, make sure to generate the older style of classfiles:

javac -target 1.1 HelloPP.java

If there are no errors, go ahead and run this example on your desktop:

java HelloPP

You should see a screen like this:

HelloPP screen shot
HelloPP in action

Now that HelloPP works on your desktop, I'll show you how to get it running on the Zaurus quickly. This process results in an ugly way to run the application. Later on I'll show you a way to deploy it that looks nicer to the user.

The first step is to transfer the class files from your desktop to the Zaurus. You can do this any way you like. I have an 802.11 card for the Zaurus, so I just use FTP to copy the files. Alternatively, you can use the Qtopia desktop software to transfer files through the USB cradle. The files you need are HelloPP.class and HelloPP$1.class. You can put them anywhere you want on the Zaurus; I placed them in /home/root.

Once you've transferred the class files to the Zaurus, use the Terminal application to open a command line. Navigate to the directory where you placed the class files. Type the following:

evm HelloPP

The same design should appear on your Zaurus. (evm is the Insignia Jeode PersonalJava runtime environment.)

Understanding the Personal Profile and PersonalJava

The Personal Profile (JSR 62) is a J2ME profile, a specification for a standard Java runtime environment. It is part of a software stack (see Introduction to Wireless Java Technology) designed for devices like the Sharp Zaurus and Compaq iPaq. It is built on the Personal Basis Profile (JSR 129), the Foundation Profile (JSR 46), and ultimately the Connected Device Configuration (JSR 36).

Personal Profile software stack
Personal Profile software stack

The Personal Profile is the J2ME incarnation of an older Java runtime environment, PersonalJava, which resembles the Java Development Kit version 1.1.8. PersonalJava runtime environments use a Java virtual machine1 (JVM), just as Java 2, Standard Edition does. Since the heyday of JDK 1.1.8, however, PersonalJava and J2SE have evolved separately. In terms of target device capacity, PersonalJava sits between J2SE and the CLDC/MIDP stack of J2ME. (Read Introduction to Wireless Java Technology for background information on J2ME.)

The Personal Profile software stack is built on the Connected Device Configuration (CDC), which specifies both a virtual machine and a basic set of APIs. The CDC is a superset of the Connected, Limited Device Configuration (CLDC) familiar to MIDlet programmers. It contains fundamental APIs from J2SE, including java.io, java.lang, java.net, java.security, and java.util. CDC implementations must support local files and datagram communications.

The Foundation Profile builds on the CDC, fleshing out its packages with support for socket and HTTP connection, among other things. The Personal Basis Profile adds AWT support with the exception of heavyweight components. The Personal Profile rounds out the software stack with support for AWT heavyweight components.

Developing Personal Profile Applications

Because the Personal Profile closely resembles the PersonalJava platform, you can use PersonalJava tools to get a quick start on Personal Profile development. Eventually Personal Profile tools will be built, but in the short term the PersonalJava tools are handy, available, and work for Personal Profile development.

The J2ME Personal Profile (and the PersonalJava platform before it) includes a JVM, just as J2SE does. Consequently, Personal Profile or PersonalJava development is very similar to J2SE development. The tricky part is that the Personal Profile's set of APIs differs from J2SE's. Setting up a development environment is a matter of installing a JDK that is close to the version of Personal Profile or PersonalJava you want to use, then obtaining compatibility classes that include the APIs that the JDK lacks.

Which JDK to use depends on which version of the Personal Profile or PersonalJava you prefer. The PersonalJava Web site contains a chart that explains the relationship between PersonalJava versions and JDK versions .

The compatibility classes are packaged as an archive; simply add this archive to the classpath you use for compiling and testing your applications.

Bear in mind that once you install the appropriate JDK and compatibility classes, many APIs may be available during development that are not actually present in a Personal Profile runtime environment. One simple example: the JDK may include the Swing user interface classes, while the Personal Profile does not. A Swing application that runs in your J2SE development environment will not run in a Personal Profile runtime environment. How do you make sure you're using only Personal Profile classes? You can check the specification as you code, but there are also some tools to help you.

The PersonalJava Emulation Environment (PJEE) tool simulates a PersonalJava device. You can use this tool to test your application in an environment that complies with the PersonalJava specification. Various versions of the PJEE are available, corresponding to different versions of the PersonalJava specification, different host platforms, and different levels of support for graphic user interface. See the PersonalJava Web site for more details. Because the Personal Profile and PersonalJava environments are so closely related, you can use PJEE as a tool for developing Personal Profile applications.

Another handy tool is JavaCheck. JavaCheck performs a comprehensive analysis of the class files in your application to see whether it complies with the specification. Like the PJEE, JavaCheck has different versions for the different PersonalJava specification versions.

PersonalJava on the Zaurus

The Zaurus comes with a PersonalJava runtime environment already installed, Jeode from Insignia Solutions. At the command line, evm invokes the Jeode virtual machine. This is the virtual machine you used to run the simple example at the beginning of this article.

Personal Profile for Zaurus

Sun has created a highly tuned Personal Profile implementation for the Zaurus. To learn how to download this implementation, send an email to ppti@sun.com. You will receive an automatic response that contains instructions for downloading and installing the software. Note that this software is for evaluation only; it is not supported and cannot be used in a product. This release is for you if you are interested in the leading edge of Personal Profile technology and would like to see a high-performance, optimized implementation.

To install the Personal Profile implementation for the Zaurus, follow the instructions in the email response from ppti@sun.com.

If you installed cvm into a directory in your path, you can type cvm at the command line to invoke the virtual machine. Use -Djava.class.path to specify a classpath. If you already have the HelloPP class installed, you can run it using cvm HelloPP.

Pretty Packaging for the Zaurus

As you've seen, it's a straightforward process to install .class files on the Zaurus and run them from the command line using evm or cvm. While this is fine for an individual developer, a packaged application should have a much smoother interface.

In this section I'll show you how to install a Java application in a way that adds it to the Zaurus's application menu. The Zaurus knows how to install .ipk files, which are archives. The archive is really a GZipped tar archive, as shown here:

.ipk package structure
.ipk package structure

The trick to packaging your application for the Zaurus is to use the right directory structure to assemble the pieces. Create the following hierarchy somewhere on your computer:

Project Directory Structure
Project Directory Structure

All of the class and resource files for the application should go in the home/QtPalmtop/java directory. Copy this application's two class files, HelloPP.class and HelloPP$1.class, into home/QtPalmtop/java.

Next you need to tell the Zaurus how to run your application. Create the following script and save it as home/QtPalmtop/bin/run_hellozaurus.

. /home/QtPalmtop/bin/installdir.sh
$QPEDIR/bin/cvm -Djava.class.path=$INSTALLDIR/java HelloPP

The first line runs a script that initializes the INSTALLDIR variable. Then the second line simply calls cvm, just as you did manually earlier. (Use $QPEDIR/bin/evm -cp $INSTALLDIR/java HelloPP if you're still using the Jeode PersonalJava environment.)

If you want your application to look nice, you'll need an icon file. Create an icon (32x32 pixels, PNG format) or download my icon and save it as home/QtPalmtop/pics/hellozaurus.png.

The next thing to create is a desktop entry file. This file tells the Zaurus how to show your application in the application menu and how to run it. Save the following file as home/QtPalmtop/Games/hellozaurus.desktop.

[Desktop Entry]
Comment=Simple Moire
Exec=run_hellozaurus
Icon=hellozaurus.png
Type=Application
Name=HelloZaurus

Notice how the desktop entyr points to the files you've already installed: the Exec= line to run the run_hellozaurus script in the bin subdirectory, and the Icon= line to the icon file in pics.

Finally, the application installation archive needs a control file. This is another text file that contains some simple information about the archive. Save the following text as control, in the same directory as home.

Package: HelloZaurus
Installed-Size: 3k
Filename: ./hellozaurus-cvm_1.0_arm.ipk
Version: 1.0
Architecture: Arm
Maintainer: Jonathan Knudsen
Description: Simple Moire Application
Section: Java

Building the archive is straightforward if you have tools that create .tar and .gz files. Linux, Solaris, Mac OS X and other Unix-like operating systems include tar and gzip programs. On MS Windows platforms, you need to obtain appropriate tools; PKZIP, ARJ, WinZip and other are readily available. On my OS X machine, I use the following script to create the .ipk file.

rm *.ipk
rm *.gz

tar -cvf control.tar ./control
tar -cvf data.tar ./home
gzip control.tar
gzip data.tar
tar -cvf hellozaurus.tar ./control.tar.gz ./data.tar.gz
gzip hellozaurus.tar
mv hellozaurus.tar.gz hellozaurus-cvm_1.0_arm.ipk

Installing Your Application

Once you create the application archive, it's a simple matter to install it:

  1. Transfer the .ipk file to the /home/root/Documents/apps/ipkg directory on the Zaurus.
  2. Select the Add/Remove Software item from the Settings tab.
  3. Click on Install Packages. You will see HelloZaurus listed. Click on it to install it.
  4. Exit from the Package Installer and exit from Add/Remove Software.

Running the application is now a simple matter of choosing the Games tab and tapping on the HelloZaurus icon.

No comments: