Sun Java Solaris Communities My SDN Account
 
Article

Do-It-Yourself MIDP on Mac OS X

 

Mac OS X ships with a wide assortment of free developer tools, but these don't include everything you need for J2ME development. The J2ME Wireless Toolkit exists only on Windows, Solaris, and Linux — although you can obtain a version of the MIDP reference implementation for Mac OS X.

This article is not an introduction to MIDP, nor is it an introduction to using the command line. If you already know your way around J2ME, XML, and Terminal.app, this article will help you roll up your sleeves, open up your command line, and start writing MIDlets on your Mac.

Downloading and Installing

The three components you'll need to download are Apache Ant, an X11 server, and the MIDP package itself.

Let's start with Ant, which is a free download under the Apache license. You can either install it manually, or use one of the several user-friendly installers to set it up for you. Such installers require administrator access, and you use them at your own risk, so get them only from a reputable source. When you're done, type ant at the command line. You should see something like this:

[home:~] michael% ant
Buildfile: build.xml does not exist!
Build failed

While that's technically an error message, it's actually good news: it tells you that Ant is correctly configured and running properly.

Next, you'll need the X Window System, also known as X11. The MIDP package is a port from Linux and it needs X11 to run, and the easiest way to get it is to download and install Apple's free beta implementation. (Mac OS X.3 "Panther" will include X11 as a standard part of the installation.)

When you're done, you'll have a new application in your /Applications directory called X11.app. Double-click it to launch it, and leave it running. An X window server doesn't look like much; it simply enables other applications to draw to the screen. Until you launch an application that needs the server, there's nothing to see.

Finally, you need the MIDP reference implementation for OS X, which is also a free download.

Please note that the CLDC and MIDP reference implementations, on which the ports for Mac OS X are based, are covered by the Sun Community Source License, which I encourage you to review. If you plan to commercialize any work derived from Sun's source code, you should plan to contact Sun to discuss commercial terms and conditions.

This package implements MIDP 1.0.3, and the only thing missing is support for serial connections. Keep in mind that MIDlets you write now will run on all MIDP 1.0 devices in use today, and on MIDP 2.0 devices when they become available.

The MIDP RI download file is in dmg.gz format so it will open as a disk image. Copy all of the contents into a directory of your choice. I called mine midp, and after the copy operation its contents looked like this:

[home:~] michael% ls -l midp
total 64
drwxrwxrwx  3 michael staff   102 Feb 3 21:27 appdb
drwxrwxrwx  5 michael staff   170 Feb 4 23:03 bin
drwxrwxrwx  8 michael staff   272 Feb 3 16:32 classes
-rwxr-xr-x  1 michael staff    89 Feb 3 21:17 demos.sh
drwxrwxrwx 16 michael staff   544 Dec 18 2002 docs
drwxrwxrwx 19 michael staff   646 Feb 3 21:27 example
drwxrwxrwx  5 michael staff   170 Feb 3 16:32 lib
-rwxr-xr-x  1 michael staff   775 Feb 3 21:26 readme.txt
drwxrwxrwx  5 michael staff   170 Feb 3 21:27 tools
-rw-r--r--  1 michael staff 21499 Sep 19 2001 usage.html

Let's test your setup before we continue. First, make sure your X11 environment is running, then open a Terminal window and cd into your midp directory. Type sh demos.sh to run a demonstration. If all is well, you should see a window like this:

Now you're ready to start writing MIDlets! For your convenience, your MIDP installation has the complete API reference in Javadoc format in the docs directory.

As a final step, you should now download the sample project template, which will help you get up and running quickly.

Configuring Your Build with Ant

Befitting Mac OS X's Unix heritage, there is a bewildering array of options for setting up your build environment, including shell scripts, make, jam, Project Builder, JBuilder, and the like. It's hard to go wrong with Ant, however. It's simple, cross-platform, well-supported, in wide use, and free, so Ant will be our build tool here.

There's an entire article dedicated to building MIDlets using Ant, and you should take a look at that before proceeding. When you get back here, we'll start with the build file from that article, but we'll need to modify it to work with our MIDP setup because that article assumes you're working with the J2ME Wireless Toolkit.

You should create a directory for your project. I called mine hello. Under that directory, the build file, build.xml, goes in a directory called build, your source code goes in a directory called src, your icons and other resources (if any) go in res, and your manifest and JAD file go in a directory called bin. (Note that the build file assumes your JAD file is called MyProj.jad and your manifest MANIFEST.MF. You should change either the build file or your filenames appropriately.) My project directory looks like this:

[home:~/hello] michael% ls -l
total 0
drwxr-xr-x 3 michael staff 102 Jul 4 11:16 bin
drwxr-xr-x 3 michael staff 102 Jul 4 11:16 build
drwxr-xr-x 3 michael staff 102 Jul 4 11:16 res
drwxr-xr-x 3 michael staff 102 Jul 4 11:16 src

The first change to make in the build file is to point the midp property to the directory where you've placed your MIDP installation. In my case, the midp directory is in my home directory.

<property name="midp" value="/Network/Users/michael/midp"/>

If you chose to download the sample project template, you can now skip down to the "Building Your MIDlet" section. If not, you need to make the following additional changes to the build file. In either case, seeing the differences between the reference implementation port and the WTK is instructive.

This MIDP distribution leaves the core classes in a directory rather than packaging them in a ZIP file, so the next change is to modify the midp_lib property to point to the classes directory. Note the property substitution syntax, ${midp}, which indicates that the classes directory should be located under the directory identified by the midp property.

<property name="midp_lib" value="${midp}/classes"/>

Where the WTK's emulator is called emulator, our emulator is called midp, so we need to make a slight change to the exec task in the run target.

Likewise, the syntax for emulator's options is slightly different, so in the -Xdescriptor option we need to replace the colon with a space, and we need specify the classpath. Furthermore, we have to tell Ant to set an environment variable so that the emulator will use X11 to display itself. Fortunately, these changes are easier than they sound.

Applying all the changes produces a target that looks like this:

<target name="run" depends="dist">
<exec executable="${midp}/bin/midp">
<arg line="-Xdescriptor build/bin/MyProj.jad"/>
<arg line="-classpath build/bin/MyProj.jar"/>
<env key="DISPLAY" value=":0.0"/>
</exec>
</target>

Finally, unless you happen to have the Jax obfuscator installed, we need to disable the obfuscation step. Code obfuscation is a good practice for MIDlet development because it effectively shrinks the size of your compiled code. For now, you should tell Ant to skip obfuscation: change the preverify task's dependency from obfuscate to compile.

<target name="preverify" depends="compile">

Now you're ready to build your MIDlet.

Building Your MIDlet

The moment of truth is upon us: from your build directory, type ant. If you encounter problems, double-check the build file to ensure that the paths to the MIDP installation are set correctly, and that the names of the manifest and JAD files match the ones you have in your bin directory. If all goes well, you will see something like this:

[home:~/hello/build] michael% ant
Buildfile: build.xml

init:

compile:
[mkdir] Created dir: /Network/Users/michael/hello/build/classes
[javac] Compiling 1 source file to /Network/Users/michael/hello/build/classes

preverify:
[mkdir] Created dir: /Network/Users/michael/hello/build/preverified

dist:
[mkdir] Created dir: /Network/Users/michael/hello/build/bin
[jar] Building jar: /Network/Users/michael/hello/build/bin/MyProj.jar
[copy] Copying 1 file to /Network/Users/michael/hello/build/bin

BUILD SUCCESSFUL
Total time: 2 seconds

The build file's default target is dist, so typing ant with no arguments invoked the dist target, whose chain of dependencies caused the init, compile, and preverify targets to be invoked, in that order.

Now let's try the run target, which will start the emulator and run your MIDlet. The run target depends on dist, so all the familiar targets will be invoked again as well. Make sure your X11 environment is running, and type the command ant run. If you run into problems, check that the exec task is correctly configured as I've described, and that your JAD file specifies the name of your MIDlet class correctly. If everything is okay, you will see the emulator in a menu, with the name of your MIDlet and its icon. Click the Launch button to start the MIDlet.

Your build cycle is now complete. From here, you can code-a-little, build, test-a-little, and repeat, ad infinitum.

Testing and Debugging

While there is no substitute for testing on an actual device, deploying to hardware every time you want to run a test is typically tedious and time-consuming enough to cause a major bottleneck in your build cycle. On the other hand, testing in an emulator is quick but it is only an approximation of actual performance. You will want to understand the nature of that approximation for each kind of emulator you use.

The Reference Emulator

The emulator that comes with your MIDP installation is a port of something called the reference implementation, meaning that it is the standard against which device makers are supposed to judge their own attempts at implementing MIDP. It's hard to do better than that for an emulator, but there are quirks.

The first thing you should always keep in mind is that the emulator runs orders of magnitude faster than actual devices, which usually have small, low-power processors. Similarly, the emulator may have more memory or color depth in its default settings than some of the devices for which you're writing your MIDlet.

Fortunately, these settings are configurable as system properties: all of the options for configuring the emulator are documented in the usage.html file in the MIDP installation. Furthermore, using Ant you can set up a different target for each scenario you need to test (for example, fourcolor, gray, onebit, slow, low-mem).

<target name="onebit" depends="dist">
<exec executable="${midp}/bin/midp">
<arg line="-Dsystem.display.screen_depth=2"/>
<arg line="-Xdescriptor build/bin/MyProj.jad"/>
<arg line="-classpath build/bin/MyProj.jar"/>
<env key="DISPLAY" value=":0.0"/>
</exec>
</target>

You should also note that MIDP's LCDUI framework allows device makers considerable freedom in how they implement the basic user interface widgets like List and Form. The reference implementation is actually worse than some real implementations, in some ways: Lists reset their selection each time they're shown, StringItems have no space between their title and their label, and Text components bear little resemblance to those you will see on actual hardware. What's more, every device maker seems to invent its own standard for placing soft buttons.

For debugging, you'll have to lean heavily on that old standby, System.out.println(). To make matters worse, the emulator returns no stack traces: Exception.printStackTrace() reports only the topmost method on the stack. You'll have to use even more printlns, but that won't be anything you can't handle.

Other Emulation Options

Device makers all provide their own emulators that give you a better approximation of the hardware. These emulators typically share the same code that runs on the devices, so they are often bug-for-bug-compatible with the hardware. None of them run on Mac OS X, however, so, short of buying VirtualPC, this is not an option.

Your only alternative, then, is the world of Pure Java MIDP emulators. There are at least two that are open source and freely available: ME4SE and MicroEmulator. Note that neither is certified as MIDP-compliant, but until the official emulators are ported they're all you've got.

Both implement parts of the MIDP API on the standard J2SE runtime, so they run anywhere desktop Java runs, and exceptions trigger full stack traces to boot. Each does things a little differently from the other, and neither is fully compatible with the MIDP specification. That diversity is actually a boon to your testing: By the time you modify your code to run well on these two emulators and the reference emulator, your MIDlet will be much better prepared for the many implementation variations of the myriad hardware devices out in the real world.

Deploying on Hardware

Of course, the point of all of this is to run your application on a mobile information device.

Because device makers don't provide the same support for loading MIDlets over a serial cable on Mac OS X that they do on other platforms (presumably due to the lack of a conventional RS-232 DB-9 port), over-the-air (OTA) installation may be your only option for deploying to hardware.

At this point you should read the article "Remotely Deploying Wireless Java Applications" for background on how OTA works and how to test it. Conveniently, Mac OS X has a built-in Apache server, but any web server will do. If your wireless device can access your server via HTTP, all you need to do is a little configuration as specified in the article and you're set.

On Apache, setting the MIME types for your files is a very simple process, if you happen to serve your JAD, JAR, and WML files from the same directory. Just add a file to that directory called .htaccess with the following contents, and you won't even have to restart the server process:

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

Another happy option for deploying your application wirelessly, if both your device and your computer support it, is Bluetooth. In particular, Bluetooth appears to be the preferred way of working with the popular Nokia 3650, and more Bluetooth-compatible devices are sure to come.

Summary

Thanks to the Unix underpinnings of Mac OS X, Mac developers now have options for J2ME development. The Mac OS X port of the MIDP reference implementation, used with a build tool like Ant, can be a productive environment for writing MIDlets. Testing and debugging can be tricky, but you can host and deploy your applications directly from your local Apache installation. It's a good time to go wireless!

For More Information

The sources linked to in this article are listed again here.

Acknowledgements

Special thanks to Jonathan Knudsen for his encouragement, to Mary Ann Rayner for her kindness, and to Brian Christeson for going easy on the copy.




Reader Feedback
Excellent   Good   Fair   Poor  

If you have other comments or ideas for future technical tips, please type them here:

Comments:
If you would like a reply to your comment, please submit your email address:
Note: We may not respond to all submitted comments.

Have a question about Java programming? Use Java Online Support.



Back To Top

Oracle is reviewing the Sun product roadmap and will provide guidance to customers in accordance with Oracle's standard product communication policies. Any resulting features and timing of release of such features as determined by Oracle's review of roadmaps, are at the sole discretion of Oracle. All product roadmap information, whether communicated by Sun Microsystems or by Oracle, does not represent a commitment to deliver any material, code, or functionality, and should not be relied upon in making purchasing decisions. It is intended for information purposes only, and may not be incorporated into any contract.