Beginning J2ME: Building MIDlets

Get a taste of MIDlet development

MIDP (Mobile Information Device Profile) applications are piquantly called MIDlets, a continuation of the naming theme begun by applets and servlets. Writing MIDlets is relatively easy for a moderately experienced Java programmer. After all, the programming language is still Java. Furthermore, many of the fundamental APIs from java.lang and are basically the same in the MIDP as they are in J2SE. Learning the new APIs (in the javax.microedition hierarchy) is not terribly difficult.

The actual development process, however, is a little more complicated for MIDlets than it is for J2SE applications. Beyond a basic compile-and-run cycle, MIDlets require some additional tweaking and packaging. The complete build cycle goes like this: edit, source code, compile, preverify, package, test or deploy.

To show how things work, and to give you a taste of MIDlet development, this article is dedicated to building and running a simple MIDlet. In this article, you'll get a feel for the big picture of MIDlet development.

Tooling up

MIDlets are developed on regular desktop computers, although the MIDlet itself is designed to run on a small device. To develop MIDlets, you'll need some kind of development kit, either from Sun Microsystems or another vendor. Remember, MIDP is only a specification; vendors are free to develop their own implementations.

The world is full of MIDlet development tools if you know where to look. Furthermore, many of these tools are freely available.

The bare bones set of tools is Sun's MIDP reference implementation. This includes the preverify tool (more on this later), a MIDP device emulator, source code, and documentation. You can download the MIDP reference implementation from Sun. However, we don't recommend using the reference implementation unless you really enjoy being in the middle of the gritty details of building and packaging MIDlets. (You should also investigate the reference implementation if you are interested in porting the MIDP runtime to a new device or platform.)

A much better tool for beginners is Sun's J2ME Wireless Toolkit. The J2ME Wireless Toolkit (or J2MEWTK, as it's affectionately known) includes a GUI tool that automates some of the tedious details of building and packaging MIDlets, providing a simple path from source code to running MIDlets. At the same time, the J2ME Wireless Toolkit is a relatively lightweight solution, almost a miniature IDE, not something that will choke your machine.

Larger IDEs are available in abundance from device manufacturers, wireless carriers, IDE vendors, and open source communities, including the following (links to tools are available in Resources):

  • Borland JBuilder X Mobile Edition
  • IBM WebSphere Studio Device Developer
  • Research In Motion BlackBerry Java Development Environment
  • Sun Java Studio Mobility
  • NetBeans IDE 4.x
  • Eclipse J2ME plug-in
  • Nokia Developer's Suite for J2ME

You can use whatever development kit you wish. We suggest you start with the J2ME Wireless Toolkit, which is easy to use and authoritative. We'll be using the J2ME Wireless Toolkit (version 2.2, or WTK 2.2). Other development environments generally use the J2ME Wireless Toolkit as a plug-in anyhow, so your experiences are likely to be similar no matter what tool you use. You'll notice details about the development environment most in this article, where we'll go into detail about the build tools and the emulators.

Debugging your MIDlets

If you are using any of the previously listed IDEs, you will have an integrated full-featured debugger for stepping through and debugging your MIDlets. If you are using the WTK standalone, and an external text editor, you can debug most of your MIDlets using the familiar System.out.println() call to output to console. The WTK maintains a console that will show all your debug and stack traces.

Creating source code

Writing Java source code is the same as it always was: use your favorite text editor to create a source file with a .java extension. The example we'll build and run is Jargoneer, a MIDlet that looks up words in the Jargon File, a comprehensive lexicon of hacker slang.

When you enter a word into Jargoneer, it connects to a server to find the definition. Running this MIDlet will allow you to appear cool in the company of your hacker friends. When someone uses an unfamiliar word, like "cruft" or "grok," you can surreptitiously key the word into your mobile phone and see a definition in a few seconds.

Jargoneer's source code is provided in the listing below. Note: You can download all of this article's code examples from the downloads page at Apress.

Jargoneer's Source Code



import*; import javax.microedition.midlet.*; import javax.microedition.lcdui.*;

public class Jargoneer extends MIDlet implements CommandListener, Runnable { private Display mDisplay;

private Command mExitCommand, mFindCommand, mCancelCommand;

private TextBox mSubmitBox; private Form mProgressForm; private StringItem mProgressString;

public Jargoneer() { mExitCommand = new Command("Exit", Command.EXIT, 0); mFindCommand = new Command("Find", Command.SCREEN, 0); mCancelCommand = new Command("Cancel", Command.CANCEL, 0);

mSubmitBox = new TextBox("Jargoneer", "", 32, 0); mSubmitBox.addCommand(mExitCommand); mSubmitBox.addCommand(mFindCommand); mSubmitBox.setCommandListener(this);

mProgressForm = new Form("Lookup progress"); mProgressString = new StringItem(null, null); mProgressForm.append(mProgressString); }

public void startApp() { mDisplay = Display.getDisplay(this);

mDisplay.setCurrent(mSubmitBox); }

public void pauseApp() {}

public void destroyApp(boolean unconditional) {}

public void commandAction(Command c, Displayable s) { if (c == mExitCommand) { destroyApp(false); notifyDestroyed(); } else if (c == mFindCommand) { // Show the progress form. mDisplay.setCurrent(mProgressForm); // Kick off the thread to do the query. Thread t = new Thread(this); t.start(); } }

public void run() { String word = mSubmitBox.getString(); String definition;

try { definition = lookUp(word); } catch (IOException ioe) { Alert report = new Alert( "Sorry", "Something went wrong and that " + "definition could not be retrieved.", null, null); report.setTimeout(Alert.FOREVER); mDisplay.setCurrent(report, mSubmitBox); return; }

Alert results = new Alert("Definition", definition, null, null); results.setTimeout(Alert.FOREVER); mDisplay.setCurrent(results, mSubmitBox); }

private String lookUp(String word) throws IOException { HttpConnection hc = null; InputStream in = null; String definition = null; try { String baseURL = ""; String url = baseURL + word; mProgressString.setText("Connecting..."); hc = (HttpConnection); hc.setRequestProperty("Connection", "close"); in = hc.openInputStream();

mProgressString.setText("Reading..."); int contentLength = (int)hc.getLength(); if (contentLength == -1) contentLength = 255; byte[] raw = new byte[contentLength]; int length =;

// Clean up. in.close(); hc.close();

definition = new String(raw, 0, length); } finally { try { if (in != null) in.close(); if (hc != null) hc.close(); } catch (IOException ignored) {} }

return definition; } }

Compiling a MIDlet

Writing MIDlets is an example of cross-compiling, where you compile code on one platform and run it on another. In this case, you'll be compiling a MIDlet using J2SE on your desktop computer. The MIDlet itself will run on a mobile phone, pager, or other mobile information device that supports MIDP.

The J2ME Wireless Toolkit takes care of the details as long as you put the source code in the right directory.

  1. Start the toolkit, called KToolbar
  2. Choose New Project from the toolbar to create a new project
  3. When the J2ME Wireless Toolkit asks you for the name of the project and the MIDlet class name, use "Jargoneer" for both
  4. Click the Create Project button and then the OK button to dismiss the project settings window

Figure 1 shows the New Project dialog box.

Figure 1. Creating a new project with the J2ME Wireless Toolkit. Click on thumbnail to view full-sized image.

The J2ME Wireless Toolkit represents projects as subdirectories of its apps directory. The following shows the contents of the Jargoneer directory after the new project is created:

 <J2ME Wireless Toolkit directory>

Save the source code as in the project's src directory. You can simply click the Build button in the J2ME Wireless Toolkit toolbar to compile the open project.

Behind the scenes, the J2ME Wireless Toolkit uses J2SE's compiler. Normally, when you're compiling J2SE source code, the CLASSPATH environment variable points to all the classes that your source code needs to know about. When you use javac to compile a file, there are some implied APIs that get included, like the classes in java.lang. With MIDlets, however, the situation is a little more complicated. Say that you use the java.lang.System class in your MIDlet. How do you (or how does the J2ME Wireless Toolkit) let the compiler know that you want to use the MIDP version of this class, not the J2SE version?

The answer is a command line option, -bootclasspath. This option lets you point to a classpath that describes the fundamental APIs against which you will be compiling your source code. In this case, this option should be used to specify the classes directory in the MIDP reference implementation installation. If you install the MIDP reference implementation, the command line looks like this:

 javac -bootclasspath \midp\classes

You will need to adjust the path to classes if you installed the MIDP reference implementation in a different location.

Preverifying classfiles

Now comes an entirely new step in building your program, preverifying. Because the memory on small devices is so scarce, MIDP (actually, CLDC, or Connected Limited Device Configuration) specifies that bytecode verification be split into two pieces. Somewhere off the device, a preverify step is performed. The device itself is only required to do a lightweight second verification step before loading classes.

If you are using the J2ME Wireless Toolkit, you don't have to worry about preverifying classfiles, and you may not even notice that it's happening when you click the Build button. If you'd like to understand more about preverifying, read the rest of this section. Otherwise, you can just skip ahead.

As you may recall, bytecode verification is one of the foundation stones of Java's runtime security model. Before a classloader dynamically loads a class, the bytecode verifier checks the classfile to make sure it behaves well and won't do nasty things to the JVM. Unfortunately, the code that implements the bytecode verifier is bulky, too large to fit on a small device like a mobile phone. The CLDC dictates a two-step bytecode verification:

  1. Off the device, classfiles are preverified. Certain checks are performed, and the classfile is massaged into a format that the lightweight second-step verifier can easily handle. This format is really just a regular classfile, with some additional data attached by the preverifier.
  2. On the device, the second step of verification is performed as classes are loaded. If a classfile has not been preverified, it is rejected.

The MIDP reference implementation and the J2ME Wireless Toolkit contain a tool called preverify that performs the first step.

The preverify tools takes, as input, a classfile. It produces a preverified classfile. You need to specify a classpath so that the tool can find the class you want to preverify as well as any referenced classes. Finally, you can specify an output directory using the -d option. To overwrite an existing classfile with a preverified version, you could do something like this:

 preverify -classpath .;\ midp\ classes -d . Jargoneer

In this example, the -d option tells preverify to write the preverified classfile to the current directory. Don't forget about inner classes, which must also be preverified.

Note: Splitting bytecode verification into two pieces like this has important security ramifications. Devices should only download code from trusted sources, using a secure method, because some bytecode verification is performed off the device. An attacker could supply malicious code that appeared to be preverified, even if it violated the rules of the full J2SE bytecode verifier. To the MIDP second-step verifier, the code would look okay and it would be loaded and run.

Sun's J2ME Wireless Toolkit emulators

The J2ME Wireless Toolkit includes several different emulators that you can use to test your applications. When you click the Run button in the J2ME Wireless Toolkit, your application is launched in the currently selected emulator.

The Wireless Toolkit devices

The J2ME Wireless Toolkit 2.2 contains four main device emulators:

1 2 Page 1
Page 1 of 2