| MIDP/CLDC | PersonalJava | |
| Industry support | Most Java-enabled mobile devices support MIDP1.0, and it is available as an add-on for many others. There are MIDP implementations for Windows CE devices, for example. Much of the development of MIDP was done on the Palm PDA range. MIDP2.0 is a significant improvement of MIDP1.0, but there is very little industry support for MIDP2.0 at the time of writing. | PJ is only supported by high-end, expensive devices, like `smart' phones and PDAs. Top-of-the-range Ericsson and Nokia phones support it, as does the Sharp Zaurus. Don't expect PJ support on a budget mobile phone |
| JDK/JVM version | Loosely based on JDK1.3, but with some striking limitations (see below). | Loosely based on JDK1.1.6 |
| User interface model | MIDP has its own user interface model, designed for very small displays. MIDP2.0 offers some substantial improvements over version 1.0, such as offering some control over the layout of data entry elements (rather than none at all) | PJ applications typically use the AWT user interface model. AWT is a very limited interface, but vastly superior to MIDP. Top-end PDAs generally offer richer user interfaces than AWT can support, and these may be made available as extensions to the PJ environment. Use of these extensions, of course, reduces portability, and makes it more difficult to debug applications |
| JVM restrictions | Strict sandboxing (no file access, for example); no floating point maths support; no finalization on garbage collection; persistent storage only available in MIDP-specific `record stores'; no native calls. MIDP devices are expected to have unimpressive CPU power, so the specification calls for part of the JVM's bytecode verification process to be carried out before execution, rather than in the JVM. As a result, standard Java compilers cannot produce MIDP code without additional software | Apart from supporting a rather elderly JDK version, PJ is a full JVM. In general, PJ apps can read and write the local filesystem, make native calls, load classes from outside the application, and make and receive network calls (hardware permitting). There is generally proper floating-point maths support. |
| Packaging and deployment | Universal, non-proprietary code deployment format based on JAR and JAD (see below) files (complicated, but well documented); well-established over-the-air (OTA) deployment provisions | No standard packaging or deployment; vendors implement their own methods of installing and configuring PJ applications; no generally accepted OTA deployment protocols |
| Development options | Use standard Java compiler with CLDC `preverifier'. Some integrated toolsets are available. Test on a MIDP emulator or real hardware device | Use standard Java compiler, test on a MIDP emulator or real hardware device, or - with some caveats - on a desktop workstation |
java.awt.Frame class. If you have JDK1.1.6,
you can get a fair idea what a PJ application will look like on the
P800 without any P800 or Symbian tools: just run your application on
the standard JVM. There are a few things to watch out for, however:
NoClassDefFoundException. This
is confusing when it is perfectly clear that the class file is available
and in the right place. The simplest way to avoid problems like this
is to compile and test with JDK1.1.6. However, this is annoying if you
already have a Java development installation based on, say, JDK1.4.1.
In this case, you can run
a more modern version of javac with the
argument -target 1.1 which
produces the right type of bytecode. To avoid using classes that
don't exist in JDK1.1.6, use the -bootclasspath to
override the compiler's location to search for standard API classes.
You can get a suitable classes.zip for the P800
from the Sony-Ericsson web site, or `beam' it off the P800 itself
(it's in c:\system\java\lib).
c:\system\apps and
d:\system\apps: applications are installed here. Typically
each application will have a subdirectory under apps,
and this will become the application's current directory when it is invoked from the application launcher.
Frame will fill the whole
display (at least, that part of it that isn't reserved for system
icons). The P800 JVM silently ignores instructions to resize the
main frame. By the same token, if one Frame creates
another, the second completely obscures the first. Thus there needs to
be some form of back-navigation on each Frame. On the other
hand, if a Frame creates a Dialog, the
Frame remains visible behind it. Unlike a workstation
JVM, the P800 JVM does not allow users full control over windows
placement, and the developer needs to take this into account.
WINDOW_CLOSING event to the top frame. If you are used
to developing for desktop systems, you will probably be handling this
event anyway, because the JVM will send it when the main window is
closed. So, in theory, a P800 application should be the same as
a desktop AWT application, but with no `close' or `exit'. In practice,
many applications for the P800 do have `exit' functionality, even
some endorsed by Sony-Ericsson (like the MobiPocket eBook reader).
classes.zip supplied with the Symbian SDK.
java_g utility
with the name of a class as the command-line argument. The
emulator's classpath configuration is described in the JDK documentation.
Basically, it is taken from an environment variable _epoc_drive_j.
This is usually set to the emulator's Java directory, under
which are directories lib, and ext. In short,
any JAR file put into ext is added to the classpath. You
can also modify the classpath on the emulator command line, but this
is reasonably well documented so I won't go into it here. What is important
is that the emulator does not honour the system CLASSPATH
environment variable. In short,
on my system I would put my application JAR into the directory
\Symbian\UIQ_70\epoc32\java\ext\; the following
commands would then launch it in the emulator:
set EPOCROOT=\Symbian\UIQ_70\
set _epoc_drive_j=%EPOCROOT%\epoc32\java
PATH=%PATH%;%EPOCROOT%\epoc32\tools
pjava_g [my_main_class]
It is a well-documented flaw (feature?) that a Java application launched
this way runs in the background and, as it doesn't have an icon in
the launcher (yet), there is no standard way to foreground it. The
emulator provides a `task manager' feature that doesn't exist in the
real P800, and you can use this to bring the application to the
foreground.
\system\Apps\MyApp on
the P800, and it is called MyJAR.jar, then I would create
MyApp.txt like this:
-cp MyJAR.jar [my_main_class]The `-cp' argument specifies the JAR file and, as it is in the application's working directory (by definition) I don't need a full pathname.
AIFbuilder
to construct them; this tool has an easy-to-use graphical interface.
You could also construct an `AIFB' file (the format of which is documented)
and use aifbuilder -generate to turn it into the appropriate
AIF and APP files. On any platform other than Windows, you could be
in trouble. I understand that the GNUPoc project describes a way
to run these tools under WINE on Linux, but this requires some fairly
extensive patching of the SDK itself. Happily, there is a way to
run Java on a real P800 without these files, as I will explain below.
With the AIF, APP, and TXT files, you can install the application on a
real P800 by copying them into their own directory under system/Apps. The application should then show up in the launcher, and be runnable.
If you've done your work properly up until now, the application should behave
much as it did in the emulator.
makesis and, like the other command-line utilities,
only runs under Windows. However,
Sony-Ericsson has released the source code for makesis, and
there are Linux ports available (see below for where to get one and
how to use it).
Documents directory in the P800, and then
use the launcher on the P800 to install it.
AIFBuilder utility
AIFBuilder
AIFBuilder utility
makesis utility (the format
is described in the Symbian documentation)
.class with the file manager, and
select it, then it launches the built-in JVM as a new process,
with the following configuration:
main() method of the
selected class
The problem with the approach to development and testing described
above is that it doesn't produce a distributable application,
nor provide a way to run the application from the launcher. So while
it may work for developers, it's not very useful for end users.
A more subtle problem is that if you run a Java application from the
file manager, you only get the JVM's defaults. You can't, for example,
run the JVM with a larger initial heap or stack (which is essential
for running large or memory-hungry applications). Happily, with a
bit of hacking you can produce a distributable application in .SIS format,
which behaves exactly like the applications produces by the Symbian
SDK, and all without using Windows.
To do this, you'll need the following things:
classes.zip from
the Symbian Web site or from the P800 itself (or use the version
that comes with the old JDK)
makesis utility, from
the GNUpoc Web site.
genaif
program. Grab
genaif.c and compile
it. This program has been hacked to produce APP files, and to
generate AIF files with the correct magic numbers in place for
PersonalJava and Symbian 7. I have only the haziest notion of
how this program works - I simply hacked it around until it
produced the same output as the Windows aifbuilder
makesis, and genaif.
genaif. If you run
genaif without arguments, it will give an example of
the required file format. It's essentially name-value pairs. This
configuration file supplies the name of the application
(perhaps in multiple languages),
and the MBM icons to include.
genaif on the UID and the configuration file, like
this, to generate an AIF file:
genaif 0xNNNNNNNN < [config_file] > [appname.aif]
The AIF file must have the suffix .aif. appname
is the name of the application; this is at your discretion, but
all the files generated by these tools must have the same name
(but different extensions), otherwise the P800 won't realize they're
connected
Run genaif again to generate an APP file:
genaif 0x00000000 0x10001734 0xNNNNNNNN > [appname.app]
Again, the APP file must end in .app. The first
two arguments are magic numbers that identify a Java application,
the third argument is the UID of the application
Create a TXT file containing the command-line of
the P800 JVM. This is what will tell the P800 what Java class to
run, and where it is to be found. It is normal practice to deploy
the application's JAR file into the same directory as the APP, AIF,
and TXT files, which has the effect that the JAR file can be specified
without a pathname. The usual command line is something like this:
-cp myapp.jar [main_class_name]
You can also use the usual command-line arguments like -ms
to change the initial heap size. NOTE: this file must not be
terminated with a linefeed character!. If you create the file
using a Linux text editor like vim it will automatically
put a linefeed on the end. This stops the application from working, because
the linefeed is taken as part of the classname. This is a horrible problem
to debug, because you can't see a linefeed on the P800. So,
my ugly method of generating the TXT file is:
echo -n "-cp myapp.jar [main_class_name]" > myapp.txt
Create a PKG file to configure makesis. The Linux
version of this tool takes exactly the same file format as the
Windows version, and this is well documented on the Symbian web site.
In brief, the PKG file contains the UID (again), an identifier to
specify the target platform, and a set of file copy operations.
You can also do clever things like conditionally specifying which
files to install, and popping up installation instructions, but
that's well documented elsewhere. For a simple application, the
PKG file will look something like this:
&EN
#{"myapp"}, (0xNNNNNNNN), 1,0,0
"myapp.aif"-"!:\system\apps\myapp\myapp.aif"
"myapp.app"-"!:\system\apps\myapp\myapp.app"
"myapp.txt"-"!:\system\apps\myapp\myapp.txt"
"myapp.jar"-"!:\system\apps\myapp\myapp.jar"
(0x101F617B), 2, 0, 0, {"UIQ20ProductID"}
The 0xNNNNNNNN should be replaced by the UID. Note that the PKG
file specifies the four essential files the application needs:
AIF, APP, TXT, and JAR. The last line identifies the P800 and
similar devices. Note that the file locations given are real
file locations in the P800 filing system. The only relativity
you get is the ability to specify `!' as the drive letter. The
installer will ask the user which drive to install on when it
reads the SIS file.
Run makesis on the PKG file, to produce a SIS file
Er... that's it.
This may appear complicated, but all the steps can be automated
in a shell script, and then it's just a case of running the
script when you want to build the SIS file.
So it is, in fact, possible to develop, test, and package PersonalJava
applications for the P800 on Linux. You don't get the Symbian emulator,
but for Java that's no great loss. My normal procedure now is to
develop using Ant on Linux, testing on JDK1.1.6, and periodically
deploy to the P800 to test that everything is still working.
PersonalJava development on the P800 itself
Some enterprising folk have ported a real javac
implementation to the P800, and the result is an application
called `jCompile'. Combined with a text editor, this makes it
possible to edit and compile Java directly on the P800. For
copyright reasons, jCompile is not supplied with Sun's JDK bootstrap
classes (java.lang.String, etc). However, these are
easy enough to obtain from Sun's Web site, and jCompile has very detailed
instructions on how to unpack the Sun JDK class library, and repack it in a way
that jCompile understands. jCompile comes with a utility called
jRun, which can run a Java class whose name is specified in a text
file. However, it might be easier to test using the file manager,
as described above.
MIDP on the P800
MIDP is a very different flavour of Java from PersonalJava. On
paper, MIDP has much to recommend it. Commercial developers should
be attracted to the universal, standardized deployment format -
this should make it possible to deploy exactly the same application
on any compliant device. MIDP applications can be deployed over-the-air
from any Web server to an Internet-capable device.
In addition, MIDP is based on a more modern
JDK version. However, although the P800 does run MIDP applications,
there are good reasons for using PJ instead.
First, MIDP is designed primarily for the least capable Java-enabled
devices. It is a good match, for example, to the Nokia 6310i mobile
phone, which has a monochrome screen of about 100x60 pixels, and
about 128 kB RAM. On such a device, your main concern when laying
out a user interface will be to ensure that it can be used
at all; aesthetics will be a nicety. MIDP has its own user
interface model, not based on AWT. This model recognizes five types
of display: Form, List,
TextBox, Alert, and Canvas.
A Form is somewhat like a Container in
AWT. However, unlike AWT a Form cannot contain
arbitrary display objects; instead is are a second set of
display objects that can only be placed inside forms. Some have
counterparts among the top-level display objects,
such as the TextField
(similar to a TextBox), and some which don't,
such as the Gauge (a progress indicator). The other
screen types should be obvious; a Canvas is a blank
page that the application can draw on, just like in AWT.
It follows that you won't be able to build and test MIDP applications
without either MIDP hardware or an emulator. Sun Microsystems supplies
an emulator as part of its (free) Wireless Toolkit (WTK), that can be
configured to look like most
real devices. Sony-Ericsson provides a plug-in for the WTK that makes
it look and act more like a real P800.
MIDP applications are heavily sandboxed, which means you can't use MIDP
to read or write data from other applications, even other MIDP applications.
MIDP applications cannot read or write files, except MIDP `record
stores', which are private to a particular application. Most worryingly,
perhaps, is that MIDP runs on an impoverished JVM. There is no
support for floating-point maths (no double type or
Double class), or for finalization of objects.
The capabilities of the P800 far exceed the anticipated capabilities
of a MIDP device. The P800 has a multi-tasking operating system,
up to 140 Mb non-volatile RAM, floating-point maths in hardware,
and a 320x240 screen with 4096 colours per pixel. Its native
user interface is far richer than AWT, and simply streets ahead of
MIDP.
In fact, there seems to be an increasing, unacknowledged acceptance
that MIDP exists to support games on mobile phones. The MIDP specification
defines specific game-related keys (`up', `down', `fire', etc) which
hardware vendors should map onto their devices' keypads. In addition,
MIDP2.0 has a specific `game API' for performing screen sprite operations.
MIDP is already finding a niche - there are hundreds
of MIDP games available. For commercial software vendors, MIDP offers
an excellent games platform: one binary distribution will work on
a large range of different devices, and users have a straightforward
way to download the software over the air. The MIDP sandbox allows users to
be confident that MIDP applications will not interfere with other
software or data on their devices. The P800 acknowledges
this tendency for MIDP to provide a games platform
in a very obvious way: when a MIDP application brings
a Canvas object to the foreground, the P800 splits the
screen in half, and displays a PlayStation-style game keypad in the
bottom half.
There doesn't seem to be any way to override this
behaviour. This has two undesirable effects - first, it looks
daft if the application is not a game; second, you lose
half the screen area.
The second reason for using PJ rather than MIDP on the P800 is that
the P800's MIDP implementation does not always follow the MIDP
specification in a predictable way. To be fair, there are places
where the behaviour mandated by the specification is not entirely
clear. However, MIDP applications on the P800 behave differently
from the same code on Sun's emulator, to a greater degree than
can be accounted for by normal inter-implementation variations.
For example, when the application switches
from one type of screen to another, any menu commands (Command
instances) associated
with the previous screen are not removed from the main menu.
This means that it is possible to invoke a menu command
associated with a display that is invisible. Whether this behaviour
complies with the MIDP specification I'm not sure, but it's certainly
not the way that Sun's emulator behaves.
However, there are certain advantages to using MIDP over PJ on the P800,
not least of which is that you don't need any P800 or Symbian
tools, and you don't need to use Microsoft Windows for any
part of the development and deployment process.
MIDP development for the P800
If you still want to develop MIDP applications for the P800, here's
one way to do it. Build and test your application using Sun's
WTK, optionally configured to better match the real P800. To test
on the real device, get the WTK to generate a JAR file.
If you want to supply the application over the air from a Web server, you will
need the `JAD' file that the WTK generates at the same time. The JAD file
contains a textual description of the application,
which the user can download before deciding whether to download the
whole application.
To install a MIDP application without deploying over the air, simply
copy the JAR file to any convenient location on the P800, then use
the P800 launcher's `install' menu command to install it.
There are other ways to develop for MIDP, but all rely on the ability
to `preverify' the bytecode before it can be executed. This process
makes bytecode verification more manageable for a device with limited
CPU power. At present, a preverifier is only available from Sun as part
of the WTK, although it can be executed on the command line or
integrated into an IDE or Ant build task.
Miscellaneous development-related issues
This section describes some other (hopefully) useful things I have
discovered about the P800. They may, for all I know, be common
knowledge, but they all took me a while to find out, so maybe I can
save you some time... These things are only loosely related to
software development, but I couldn't think where else to put them.
Creating eBooks and large text documents
If you want to read large documents on your P800, you could supply
them as PDF files or Microsoft Office documents, and use the built-in
Viewer application. However, the Viewer is slow, and doesn't render
PDF all that well. With large documents, it appears to read the entire
contents into memory before displaying anything. If you just want
to read eBooks, or dictionaries, you might be better off with a
specific eBook reader. The product endorsed by Sony-Ericsson
(and supplied pre-installed on some, but not all, P800s) is the
MobiPocket Reader. A trial version of this program is available
free of charge from the MobiPocket web site; the commercial
version is reasonably-priced at about $20, and offers the ability
to rotate the display into landscape mode,
so you read with the P800 on its side.
This is surprisingly effective, although I suppose you can get used
to reading in portrait mode eventually.
MobiPocket has its own file format, and there is a substantial business
in supplying eBooks and dictionaries in this format. The MobiPocket Reader
format supports images and hyperlinks, and can be generated from
HTML using a proprietary converter from MobiPocket. This is also available
free on a trial or `personal use only' basis; the problem with the
free version is that the documents it produces are festooned with
copyright warnings, which is a minor irritation. A bigger problem with
the MobiPocket converter is that it is only available for Windows.
It isn't well documented, but MobiPocket reader also supports other
file formats, in particular the formats used by Palm devices. Converters
for these formats are widely available, and not just for Windows.
For example, there is a utility called txt2pdbdoc (do a Google search)
written in plain, ordinary C that can convert plain text to the PDB
format that Palm readers use. MobiPocket can read this format perfectly
well, and it is automatically launched if you click a PDF file
in the P800 file manager. It is straightforward to compile
txt2pdbdoc, and this will give you a way to view any large
text file using MobiPocket.
A command line shell for the P800?
Symbian produce a utility called `eshell' that provides basic
command-line functionality on certain mobile devices. This may be helpful
for developers. However, as far as I know this application is not
available for the P800; I'm not sure why.
Process management
The P800 understands the concept of a process, and supports a measure
of preemptive multitasking. Using the qfileman file manager
you can get a list of running processes, and send a `close' signal
to an unresponsive one. However, on a PersonalJava process, all
this does is to send the WINDOW_CLOSING AWT event, which the application
should handle by shutting itself down. The problem is that if the
application is badly broken, it may be too far gone to respond to the
event. There doesn't seem to be any way to forcibly destroy an unresponsive
application, short of rebooting the P800.
©1994-2003 Kevin Boone, all rights reserved