So you want to be a J2ME developer? Get ready for quite a ride.
Part one of this two part article: Java 2 Micro Edition and the Kilobyte Virtual Machine
If you have any experience creating Java applications or applets, then programming for the KVM won’t seem like such a stretch. The steps are basically the same:
- Write your program
- Compile it
- Preverify it
- Test It
- Debug It
- Release it!
The only thing that should set off your mental alarms is step number 3 — preverification. This may sound weird and complicated, but is actually quite easy. The purpose of preverification, theoretically, is to go through your bytecode and set hints up so that the actual verification of bytecode on the Palm will happen much more quickly, saving you valuable startup time.
Getting Set Up
For the sake of this tutorial, we’ll assume you’re using a Windows system and developing on the C drive. But if you’re a Linux user, or even playing on Mac, this should still be useful — just make obvious changes to the directory structure and file syntax.
So let’s start from the beginning. There’s quite a bit of setup work required before you can begin programming. Also, I recommend that you clean out your Palm pilot’s memory as much as possible. You may also want to use a program like FlashPro to give yourself a few extra megs to work with.
Now, the first thing you’ll need is Java itself (JDK1.2 2 or better), which has all the engines and libraries necessary to compile code. If you don’t already have the JDK, you can grab it here
Next, download the CLDC from Sun’s site. If you’re not already a member of the Sun Download Center, you’ll have to register and get a valid name and password. You should wind up with two files:
j2me_cldc-1_0-src-winsol.zip
j2me_cldc-1_0-src-palm_overlay.zip
Unzip the first file to your root directory — it will create a directory called
j2me_cldc |
j2me_cldc |
In the
bin |
KVM.prc |
KVMutil.prc |
Before you can really begin, though, you’ll need to compile your own set of tools. Why Sun didn’t just include them compiled for you is anyone’s guess. In the DOS command line, move to the
c:j2me_cldctoolspalmsrcpalmdatabase |
javac -d c:j2me_cldcbinapiclasses *.java
Just for uniformity’s sake, you’ll also want to copy
Wrapper.prc |
DefaultTiny.bmp |
c:j2me_cldctoolspalmsrcpalmdatabase |
c:j2me_cldcbinapiclassespalmdatabase |
Good. You’re ready to roll!
Write Your Program
Just like an applet is based on the
java.applet.Applet |
com.sun.kjava.Spotlet |
com.sun.kjava.* |
Enough talk. Let’s look at some code. Who could pass up the wonderful cliche of a nice Hello World program? This version will display the words "Hello World" along with a button saying "Goodbye World". When you tap the button, the program will die a tragic death.
Here it is:
import com.sun.kjava.*;public class HelloWorld extends Spotlet { // The Graphics object is always a singleton static Graphics g = Graphics.getGraphics(); // A button allowing us to quit Button byeButton; /** * Create the Spotlet, register event handlers. */ public static void main(String[] args) {(new HelloWorld()).register(NO_EVENT_OPTIONS); } /** * Create any components */ public HelloWorld() {// create the buttonbyeButton = new Button("Goodbye World",60,110);paint(); } /** * Draw the screen and all components! */ private void paint() {g.clearScreen();g.drawString("Hello World",60, 80);// Always draw components here, as wellbyeButton.paint(); } /** * Handle a pen down event. */ public void penDown(int x, int y) { // Does (x,y) fall within the button's boundaries?if (byeButton.pressed(x,y)) { System.exit(0);} }} |
Pretty easy, eh? Note that
paint() |
Graphics.getGraphics() |
Compile and Preverify It
Now you’ll need to compile the Java into a class file. This is done the same way you’d compile any Java program, really — just be sure to include the CLDC classes. For now, I’ll spell out the entire process step by step. You may notice that some of these commands get a little lengthy! I highly recommend you plop all these steps into an easy batch file. This can serve as a quick makefile to compile and preverify all your code.
First, create a working directory such as
C:working |
HelloWorld.java |
javac -g:none -classpath c:j2me_cldcbinapiclasses;. -bootclasspath
c:j2me_cldcbinapiclasses HelloWorld.java
This will create a
HelloWorld.class |
c:j2me_cldcbinpreverify -classpath c:j2me_cldcbinapiclasses;.
HelloWorld
The HelloWorld code will be verified and placed in a new output directory, beneath the current working directory.
Test It
To quickly see the program, Sun includes a utility called
kvm.exe |
c:j2me_cldcbinkvm -classpath c:j2me_cldcbinapiclasses;output
HelloWorld
When done executing,
kvm.exe |
Debug or Release It
Everything look good? Then let’s actually create a Palm application! You’ll need to run the MakePalmApp class which you compiled at the beginning of this tutorial. The easiest way to do this is to change to the
c:j2me_cldcbinapiclasses |
java palm.database.MakePalmApp -v -bootclasspath
If all goes well, a nifty
c:j2me_cldcbinapiclasses -classpath c:workingoutput HelloWorld
HelloWorld.prc |
To be cautious, you should install KVM.prc on a Palm emulator such as POSE. This allows you to test our your application right on your Windows desktop. Start the emulator and choose the Install Application/Database menu item. Select the
HelloWorld.prc |
You can now easily debug your program. Run it and put it through its paces. You should use the KVMUtil app to set the maximum heap size and to pipe
stdout |
stderr |
System.out.println() |
When you’re ready for the big leagues, simply install the final
HelloWorld.prc |
Final Tips
As you go forth into the world coding Spotlets more complicated than HelloWorld, be sure to remember that every byte counts! Try to avoid Hashtables and Vectors, and recycle any objects you no longer need. For example, instead of creating two buttons on two separate screens, try to merely change the label on an existing button. Avoid using costly operations like string concatenations use a StringBuffer instead. As for interface design, remember your audience and the limitation of the device. Use few, large, simple components that require as few stylus presses as possible to get to.
While your application is running, you can sniff out the memory using
Runtime.getRuntime().freeMemory() |
Runtime.getRuntime().totalMemory() |
Runtime.getRuntime().gc() |
Since the
com.sun.kjava |
Finally, I highly recommend you use a code packer or obfuscator to compress your bytecode as much as possible. A good obfuscator such as IBM’s jax can make your final application as much as 30 percent smaller!
Resources
The complete J2ME and CLDC API and other bits of documentation are in the
c:j2me_cldcdocs |
For some great tutorials and sample programs, check out:
http://webdev.apl.jhu.edu/~rbe/kvm/
Visit the J2ME Archive with tons of sample applications, many of which include source code:
http://www.billday.com/KVMArchive/
About the Author
David Fox is vice president of games at PlayLink, Inc. He’s also the author of numerous books and articles about cyberculture and technology.