Life Outside The Sphere
Building Palm Applications with WME
Debugging, profiling,
packaging -
whatever you want, WSDD can
do it all. IBM's WebSphere Device
Developer (WSDD) is a sophisticated
development platform for IBM's WebSphere
Micro Environment (WME, also known as J9).
Based on Eclipse, it's just right for those who like to work
with Eclipse. The problems start if you prefer to use some other
IDE or you believe in automated, continuous integration. This
article will show you how to master using WME without WSDD.
WSDD uses Ant build scripts, but effectively hides the
implementation of its special tasks for the SmartLinker
jxelink and other tools. If you want to build a WSDD project
outside of WSDD, you can't rely on automatically generated
Ant build files. This makes it hard to build a project from the
command line and therefore rules out automatic builds. The
necessary tasks are simply not accessible. On top of projects
not being exportable, it's fairly difficult for inexperienced
users to import an existing project into WSDD.
With this said, why would you use WSDD if it locks you
in? Well, as mentioned before, it has a couple of nice features
and - this is probably the main reason - if you want to use
WME you have to install WSDD. IBM unfortunately does not
offer WME without WSDD. Also since Big Blue seems to concentrate
its documentation efforts on the IDE rather than the
VM, it's only natural to use the IDE for convenience.
Luckily all the WSDD's custom Ant tasks are included as
command-line tools in the WME. This allows us to call them
using the <exec> task. Admittedly, there is a bit of irony here,
because some of these tools were originally written in Java.
Palm as an Example
Let's look at an example that shows how to build a deployable
application for J9 on Palm using Ant. To reference the base of the
J9 installation, it makes sense to define a corresponding property.
The J9 folder is usually installed in a subfolder of IBM/Device
Developer/wsddx.y called ive, therefore we name the property
ive. For the etymologists among you: ive is short for "IBM
VisualAge Embedded," short for "IBM VisualAge Embedded
Systems, Java Edition," which is the original name for VAME or
"VisualAge Micro Edition," WSDD's successful predecessor (winner
of the 2002 JDJ Reader's Choice Award for Best J2ME IDE).
The first step in producing our application is to compile
the Java classes. IBM recommends using the J9 compiler j9c.
Like all other J9 tools, j9c can be found in the folder
${ive}/bin. Experience shows that you're probably equally
well off with a Sun compiler. To compile for a specific profile
you have to include its classes in the bootclasspath. Typically
you'll find the appropriate classes in ${ive} /lib/jcl<yourProfile>/classes.zip. Don't ask me why IBM doesn't stick to
the convention of using JARs instead of zips. However,
equipped like this, compiling should be a piece of cake.
<javac srcdir="src" destdir="classes" bootclasspath=
"${ive}/lib/jclCldc/classes.zip"/>
Once you have compiled all the sources, package them
into the J9 archive format JXE (Java eXEcutable). This is done
with the jxelink SmartLinker - a tool that not only packages,
but also completely rearranges the bytecode. For platforms
other than Palm and QNX it can even compile bytecode into
native code (ahead-of-time compilation, AOT). Because of
space constraints I won't delve into the many options of this
tool; I'll only describe how to call it from Ant. Also, because
there are so many options, it makes sense to use an extra file
for them, just like WSDD does. The location of this file can be
passed as an argument to the jxelink executable with a prefixed
@. To access properties defined in the Ant file, you can
declare macros for the link option file, for example:
<exec
executable="${ive}/bin/jxelink.exe">
<arg value="-macro"/>
<arg value="BASEDIR=${basedir}"/>
<arg value="-o"/>
<arg file="jxe/MyApp"/>
<arg value="@${basedir}/palm.link"/>
</exec>
This code sets the macro BASEDIR to the same value as the
property ${basedir} so that we can pass it into the options file
${basedir}/palm.link, then we can reference it with double curly
parentheses like this {{BASEDIR}}. For example, if you put the line
"-cp "{{BASEDIR}}/SomeLib.jar"" into the link options file, ${base
dir}/SomeLib.jar will be added to the SmartLinker's classpath.
As the maximum segment size for the Palm is 64KB, jxelink
has to be configured to produce multiple JXE files for applica-
tions exceeding this limit. Therefore it usually makes sense to
specify a separate output directory. In the previous code snippet
we achieve this with the -o option. As a side note, this also
means that each of your compiled classes must not be larger
than 64KB, which can be tricky when you're using large arrays.
Once you have produced the necessary JXE files, you can
proceed to build Palm resource files. If you are familiar with
Palm development, you've probably already used the Palm
resource compiler PilRC. This free tool compiles GUI definitions
into binary resources, which you can use from your
code. This makes sense, particularly when you're using the
nongraphical CLDC (Connected Limited Device Configuration)
because you want to reduce the footprint or escape the
MIDP sandbox, but still need to use a GUI.
Like other VMs, J9 comes with wrapper classes for PalmOS
(located in ${ive}/ runtimes/ palmos/68k/ ive/lib/ palmos.zip)
that let you call the needed OS functions for presenting a GUI
defined with PilRC. As the wrapper is fairly thin, this unfortunately
means that you have to manually allocate and free
memory. To those of us who got to appreciate garbage collection,
this is really nasty.... However, to compile our GUI
resources we simply invoke PilRC with the <exec> task.
<exec executable="pilrc.exe">
<arg file="MyApp.rcp"/>
<arg path="bin"/>
</exec>
The first argument is the filename of the resource description
file and the second is the output directory for the compiled
results. Again, for brevity, I will not explain the PilRC file
format as the compiler comes with a comprehensive and
easy-to-understand manual.
Now we are getting to the final step: building
the PRC (PalmOS Resource Collection) file. For
this purpose we use J9's jxe2prc command-line
tool. It takes all your compiled code and packages
it into an executable PRC file. As we have to pass
all the binary resource files on the command line,
we need to build a corresponding property that
contains all the filenames. We'll build this property
by creating a <fileset> that contains all the
binary files and then convert this file collection
into a single property using the <pathconvert>
task. Note that in order to avoid problems with
spaces in the base directory, we substitute the
base directory ${basedir} with a dot "." using <map>.
<fileset dir="bin" id="bin.files.id">
<include name="*.bin"/>
</fileset>
<pathconvert pathsep=" " property="bin.files" refid="bin.files.id">
<map from="${basedir}" to="."/>
</pathconvert>
Now that we can reference the files generated
by PilRC, we call jxe2prc with the appropriate
arguments. These are (in this order):
The four character Palm creator ID
Your application name
The main JXE file and all bin files we just generated
Name of the output file
<exec
executable="${ive}/bin/jxe2prc.exe">
<arg value="myid"/>
<arg value="MyApp"/>
<arg file="jxe/MyApp.jxe"/>
<arg line="${bin.files}"/>
<arg file="MyApp.prc"/>
</exec>
Done.
With the help of the Palm install tool you can now
synchronize the freshly built PRC file to your Palm and take
your application for a spin - provided that you've already
installed J9. This is done by synchronizing the PRC files found
in ${ive}/runtimes/ palmos/68k/ive/ bin to your Palm. You'll
need only one of the files, either midp20.prc or cldc20.prc,
depending on which of the two you want to use.
Chances are you'll want to try your application out in the
emulator before you actually test it on a real device. To conveniently
start your application with Ant, first create a Palm emulator
session file (psf) with J9 already installed. To create this
session, just install the PRC files from ${ive}/runtimes/palmos/
68k/ive/bin in a session with a clean Palm ROM and save the
session - e.g., under j9cldc_run.psf (see sidebar on how to
obtain a ROM file). Then start the emulator like this:
<exec executable="emulator.exe">
<arg value="-psf"/>
<arg file="j9cldc_run.psf"/>
<arg value="-load_apps"/>
<arg file="MyApp.prc"/>
<arg value="-run_app"/>
<arg value="MyApp"/>
<arg value="-quit_on_exit"/>
</exec>
This task will automatically install and start your application.
The -quit_on_exit option causes the emulator to automatically
shut down once you exit your application. If you
don't specify the -quit_on_exit option, it's crucial that you don't
save your emulator session. Otherwise you won't have a clean
environment the next time you start your application this way.
If you're like every other developer, something is probably
buggy in your application. The emulator lets you write to
STDERR and STDOUT, but System.err.println-debugging is a
little backward and certainly a time-consuming matter. What
you really need is a debugger. As WME supports the Java
Debug Wire Protocol (JDWP), you can attach the debugger of
your choice to J9. Just take a short detour.
First you need to tell J9 that it should start in debugging
mode. For this purpose, load the j9cldc_run.psf profile you
created earlier, open the "Prefs" application, and select "J9
Java VM" (see Figure 1). Then check the "Enable Debug"
checkbox (see Figure 2) and save the profile under the name
j9cldc_debug.psf. This is now your debug base session.
Figure 1 |
Figure 2
|
J9 does not support JDWP directly. When linking with jxelink,
all the debug symbols are stripped out of the JXE and put into a
symbol file to minimize the JXE's size. Therefore your debugger
needs to communicate with J9 through a tool called j9proxy. It
takes the debuggee's and the debugger's addresses and the symbol
file as arguments. The symbol file is located in the same
directory as our JXE file and has the file extension sym.
All we have to do now is start the j9proxy, our application,
and the debugger. We can easily start the proxy and the application
in an Ant target.
<parallel>
<exec executable="emulator.exe">
<arg value="-psf"/>
<arg file="j9cldc_debug.psf"/>
<arg value="-load_apps"/>
<arg file="MyApp.prc"/>
<arg value="-run_app"/>
<arg value="MyApp"/>
<arg value="-quit_on_exit"/>
</exec>
<exec
executable="${ive}/bin/j9proxy.exe">
<arg value="localhost:8096"/>
<arg value="localhost:8097"/>
<arg file="jxe/MyApp.sym"/>
</exec>
</parallel>
Note that we put the two <exec> tasks inside a <parallel>
container task in order to start both the application and the
proxy at the same time. With this setup we expect the Palm
application to fulfill the JDWP server role, listening with a socket
on port 8096. Our debugger needs to be configured to use a
socket as a transport layer to attach to the proxy, which is listening
on port 8097 for the debugger's connection. The proxy in
turn connects to the application on the Palm (see Figure 3).
Figure 3
Once we've started the Ant target we just need to start our
debugger and we're ready to roll. While debugging, resist
using the many optimization options jxelink has to offer.
Neither obfuscation nor inlining is very conducive to debugging
- you may end up waiting for a long time before the
application hits any breakpoints, simply because the line of
code your breakpoint is referencing may not exist anymore.
There's no support for profiling J9 for Palm applications, so
System.err-timestamps are your best bet. As the time inside the
emulator is not the real time and usually goes by faster than on
your PC, these timestamps are also a useful reality check about
how slow your application would be on a real device.
Conclusion
All in all IBM delivered a successful J2ME implementation,
which can be integrated in a continuous integration software
development process - thanks to the included command-line
tools. Whether you like WSDD or not is a matter of taste.
Anyhow, you can get around it. And if you run into problems on
the way, just drop a line to the support newsgroup. Usually the
folks from IBM/OTI answer quickly and with great expertise.
How to Obtain a Palm ROM File
There are two ways to obtain a Palm ROM file:
1. Become a member of the PalmSource (the software side of Palm) developer
program and download ROMs from the program's Web site.
2. Transfer the ROM from a Palm device to your desktop machine using the
ROM Transfer.prc file that comes with the Palm emulator. Directions are
included in the emulator's manual.
Either way works equally well. However, to deliver your application to a
wide audience with many different Palm devices, join the Palm developer
program and test your application with as many different ROMs as possible.
MIDP on Tungstens
The WME release included in WSDD 5.5 officially does not support Palm
Tungstens. If you're just interested in deploying MIDP 1.0 applications on the
Palm, look at the WME Toolkit for PalmOS developers, which supports Tungstens
and is freely available from Palm. The toolkit lets you convert MIDP applications
into PRC files for J9. Palm and IBM announced that future Tungsten devices will
come with J9 preinstalled. Owners of Tungstens W, T2, and C who bought after
October 1, automatically received a WME license bundled with their device.
At the time of writing IBM had only published a Technical Preview for their
upcoming WSDD 5.6 release, which will also support Palm Tungsten devices.
What's in an Acronym?
Confused by all the acronyms? You're not alone. Let's try to get it all
straightened out.
Java Micro Edition (J2ME): Basically Java for small devices.
Connected Limited Device Configuration (CLDC): J2ME configuration for
small devices.
Mobile Information Device Profile (MIDP): A profile based on CLDC, designed
to extend and enhance the J2ME Connected Limited Device Configuration.
WebSphere Studio Device Developer (WSDD): An integrated development
environment (IDE) for J2ME. Not to be confused with the Web site called
WebSphere Developer Domain (WSDD).
WebSphere Micro Edition (WME): IBM's implementation of J2ME.
This includes the JVM J9, originally written by the IBM subsidiary OTI.
Palm Resource Compiler (PilRC): A little freeware tool that compiles textual
GUI definitions into binary resources.
Java Debug Wire Protocol (JDWP): An element of the Java Platform
Debugger Architecture (JPDA) that defines how debugger and debuggee
communicate with each other.
Palm OS Emulator (POSE): Free hardware emulator for Palm OS, published under GPL. Can only be used for Palm devices with Palm OS versions < 5.0. The emulator mentioned in the article always refers to POSE, not the newer Palm OS Simulator.
Palm OS Simulator: Palm OS 5.x recompiled for a desktop machine.
IBM VisualAge Embedded (IVE): Short for "IBM VisualAge Embedded
Systems, Java Edition", which is the original name for "VisualAge Micro
Edition" (VAME), WSDD's predecessor.
Resources
WME: www.ibm.com/software/wireless/wme/
WSDD: www.ibm.com/software/wireless/wsdd/
WSDD newsgroup: news:news.software.ibm.com/ibm.software.websphere.studio.device-developer
PilRC : www.ardiri.com/index.php?redir=palm&cat=pilrc
POSE : www.palmos.com/dev/tech/tools/emulator/
Palm Simulator : www.palmos.com/dev/tools/simulator/
JPDA/JDWP: http://java.sun.com/products/jpda
MIDP WME Toolkit for PalmOS: http://pluggedin.palm.com/regac/pluggedin/Toolkit
Project skeleton: www.sys-con.com/java/sourcec.cfm
Author Bio
Hendrik Schreiber develops data synchronization solutions utilizing SyncML and J2ME/J2EE for Nexthaus in Raleigh, North Carolina. He is also co-author and author of two German
Java-related books, published by Addison-Wesley.
hs@tagtraum.com