Some notes on Java development for the Sony-Ericsson P800

This article outlines the process of developing Java applications for the Sony-Ericsson P800 PDA phone, and discusses the trade-offs between the PersonalJava and MIDP environments. It also gives some suggestions how to do PersonalJava development for the P800 under Linux, without using any Symbian-specific tools.

P800 Java programming overview

The P800 supports two completely different Java runtime environments: PersonalJava (PJ) and MIDP/CLDC. Strictly speaking, `MIDP' (MIDlet Profile) is an API, and CLDC (Connected limited device configuration) is a JVM. In practice, MIDP and CLDC are nearly always found together, so I will use the term MIDP to cover both in this article. MIDP is part of the `J2ME' set of standards, and is considered to be the more modern of the two. PJ is loosely based on JDK1.1.6, with a few extensions and a few restrictions. The J2ME standards support a range of different JVMs and API sets, of which MIDP caters for the smallest, most impoverished devices. In the same set of standards is, for example, CDC/Personal Profile, whose capabilities are broadly similar to PJ. However, the P800 does not support CDC/Personal, nor does any other device on the market as far as I can tell. The problem with PJ is that it does not fit neatly into the J2ME standards, and so is not supported by Sun Microsystems any more (at the time of writing, Sun had just issued an `end of life' announcement for PJ. However, there are a huge number of top-end PDAs and phones that continue to support it). Although version 2.0 of the MIDP specification has just been finalized, the P800 only supports MIDP1.0. I understand that a firmware upgrade will be available shortly. Of course, if you are a commercial developer you can't expect widespread MIDP2.0 support just yet.
       So, in short, when developing Java applications for the P800, you have to choose between PJ, which is a full-featured JVM - albeit rather old-fashioned - and CLDC/MIDP, which is designed for very limited hardware. The following table summarizes the similarities and differences between the two.

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

The P800 SDK and emulator

Sony-Ericsson insists that to develop PJ applications, you need to download the full Symbian/UIQ software development kit (available from that Company's web site, and now free of charge). This SDK includes a C++ compiler and a Perl interpreter, among other things, which are of little interest to a Java developer. The total package comes to about 600 Mbytes. It is not entirely clear which bits of this package you really need. You can develop and test PJ application quite simply using JDK1.1.6, which is widely available. The SDK package does contain a number of things which are quite useful to the Java developer: The SDK tools work only under Windows (sadly), but I understand that the command line tools can be made to work on Linux under a DOS emulator.
       For MIDP development, you don't (in theory) need any Symbian-specific tools or SDKs. You can use Sun's Wireless toolkit to produce a MIDP-compliant JAR file, and deploy it directly to the P800. However, you may find the emulator useful to get a feeling for how the application will look on the P800 itself. It's worth bearing in mind that the emulator is not specific to the P800, but to the Symbian operating system. The customizations supplied with the Ericsson version give it the P800 look-and-feel, but it doesn't give a perfect emulation.

PersonalJava on the P800

A PJ application is just an ordinary Java application, based on the AWT user interface model. An application's main screen is usually based on the 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:

PersonalJava using the SDK and emulator

Sony-Ericsson recommends certain IDE tools for development for the P800, but in practice most developers seem to use the command-line tools that come with the SDK. Whether you use the IDE or not, the approved tools are onl available for the Windows platform (of which, more later). The `approved' development and deployment procedure with these tools is as follows. If this process seems complicated, it is. Writing the Java is the straightforward part. To sum up, the packaging and deployment process is:

PersonalJava development on Linux without Symbian tools

There are two problems with the process described above. First, it only works on Windows, or at least on Windows emulators. Getting it to work under an emulator is not straightforward, but it is reasonably well documented. Second, it only works on Windows. Like many developers, I prefer to avoid Windows altogether. Happily, it is possible to do nearly all of the development and testing of PersonalJava apps using Linux, and without any special tools.
       This approach is practicable because, in fact, PJ applications look much the same on a P800 as they do in a workstation JVM. If you take into account the issues of screen sizing, fonts, and directory structure described above, you should be able to get a long way without using a Symbian emulator or even a real device - just run your applications on a workstation using JDK1.1.6 (or thereabouts). You can even mock up the P800 filesystem structure on your development workstation, and simulate the P800 classpath. Of course, this won't work if your want to use P800-specific or Symbian-specific APIs, but for most applications you won't need to. To test on a real P800, you need a way to tell it to run Java apps. There are essentially two ways to do this. First, you can copy the Java class files to some convenient directory on the P800, then run the main class directly. Second, you can package up a .SIS file and install it as you would any other application. To do either of these things, you need some way to get the files onto the P800. I use bluetooth to do this; for hints on getting the P800 talking to Linux see this article. There are a number of ways run a Java class without packaging an application; I have had most success using the `qfileman' file manager that is available free-of-charge from Symbian. qfileman is a simple file manager; that is, it can move, copy, delete, and execute files. It shows a graphical view of the real filesystem structure on the P800, stripped of the abstractions provided by the launcher and the built-in applications. It turns out that if you find a Java .class with the file manager, and select it, then it launches the built-in JVM as a new process, with the following configuration: Using this technique it is therefore possible to develop and test applications on a workstation and a real P800, without using any proprietary Symbian tools.

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:

Here are the basic steps to generate a SIS file using Linux, makesis, and genaif.
  • Write your code in the usual way, and test it under the JDK1.1.6 JVM
  • Build your code into a JAR file; again this is standard stuff
  • Create a configuration file for 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.
  • Choose (or ideally obtain from Symbian) a unique ID for the application. For development, it is considered acceptable to use an UID in the range 0x01000000-0x0FFFFFFF.
  • Run 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