| Java ME Mobile Phone Applications - The Good, the Bad and the Ugly |
| Written by Kon Katsaros | ||||||||
| Thursday, 31 May 2007 00:00 | ||||||||
Recently I was asked to develop a mobile phone application for a customer using Java Micro Edition I see many parallels between Java ME and the movie “The Good, The Bad and The Ugly”. In this popular spaghetti western, “The Man with No Name” (AKA Blondie) uses his wits and skills to make his opponents ineffective. In a similar manner, I believe that Java ME vanquishes the various problems associated with developing mobile phone applications - something I will be covering in detail. Also in the movie we have “Sentenza”, a villain trying to stop Blondie. So too, Java ME has some bad points, but just like Sentenza, they can be killed off. I’ll be describing some of these traps and problems, and how I’ve managed to work around them. Finally, we have “Tuco” the bandit - a particularly ugly character. Java ME and its operating environment also have some rather ugly characteristics and unfortunately, just like in the movie, they can’t be killed off. However, they can sometimes be distanced and avoided. So just in the same way that Blondie triumphed over both Sentenza and Tuco, Java ME can be used to deliver excellent mobile phone applications, with all major obstacles overcome. Ok, so maybe I’m stretching the parallels a bit, but I think you understand what I’m getting at! Although this discussion is split along these lines, my intention is not for it to be used as a comparative analysis of Java ME. For make no mistake about it: I’m definitely a fan of the Java ME. Indeed, if you could weigh the bad/ugly features, they might come to a few kilograms, whereas in comparison the good features would weigh several tons. The bad/ugly aspects are no more than an irritation, not a reason for avoiding it. So if you’re reading with an interest in evaluating Java ME against other mobile phone application technologies, then I can give you a recommendation now – USE IT! Alternately, if you’re already using Java ME, there’s something here for you also. For I’ll be describing observations obtained “from the coal face”, ie whilst developing real applications. Many Java ME issues and traps will be described, both to warn and advise developers traveling the same path. Finally, before we continue, you should note that whilst Java ME can be used on all sorts of devices, my experience has only been with developing applications for mobile phones. As such, any further discussion will be centered on phones. What is Java ME?For a while, I couldn’t come to grips with exactly what Java ME was. There seemed to be specifications all over the place and some software that you could run on a PC, but little relationship between this stuff and real mobile phones. The usual definition goes something like: “Java ME is a collection of APIs for the development of software for resource-constrained devices (such as PDAs and mobile phones).” However, this suggests that Java ME is just a bunch of documents - what does it really mean when you’re working in the real-world? Well, it means that Sun has come up with some specifications that describe how this technology should work. Further to that, they've has also made available a Reference Implementation (RI) of these specifications. Even better, mobile phone vendors have created Java ME implementations which operate on their specific phone models. So how do you put the Sun RI onto a real mobile phone? Well, you can’t - it isn’t possible. Sun’s RI has been compiled to work on a PC, and as such won’t run on any mobile phone device. It is only used to test Java ME applications that you have written on your development platform (usually a PC). So on which real devices can you run your Java ME application? Well, hundreds of mobile phone models have a core Java ME implementation already installed at the factory. Java ME implementations have been developed by mobile phone vendors like Motorola, Nokia, and Sony-Ericsson. Your Java ME application will automatically use this implementation when it is executed on the phone. So in addition to the previous definition, it’s also useful to state explicitly that Java ME implementations are pre-installed and available on devices, providing a virtual machine for Java ME applications to execute within. Hopefully that explains it a little more. The GoodFirst, let’s briefly cover some of the great things about Java ME. This will also give us a little background about how it works. Extensive Core FeaturesThe core features provided by Java ME implementations cover most things you would ever want your application to do on a mobile phone. This includes:
Many (but not all) newer Java ME implementations (phones less than two years old), also provide additional features, depending on the device capabilities. For example
The Java Community Process website holds all the Java ME-related specifications, which describe optional functionalities that can be provided by an implementation if the vendor chooses to include them. There are over 80 sets of Java ME-related specifications currently available. For example, if a device has GPS support, then the implementation on that device may provide the Java ME Location API. This would allow applications to retrieve and use GPS coordinates. It’s EasyIt’s easy to develop a Java ME application if you already have experience with Java. In fact, Java ME development involves using a cut-down version of Java Platform, Standard Edition (Java SE). Many of the classes and interfaces are the same as the ones in Java SE (for example, String, Thread, Runnable, Reader and Writer). The real difference is that, as opposed to Java SE, there are just a lot less classes in Java ME. Indeed, it could be argued that developing a Java ME application is simpler than developing a Java SE application. Device Implementation AvailabilityJava ME is everywhere! Java ME implementations are installed on hundreds of different types of mobile phone handsets, which results in it being available on millions of mobile phones world wide. If you wish to deliver an application to the general public on an assortment of different phone devices, a Java ME application is one of the few options available right now. For a list of devices which support Java ME, see here. PortabilityJava ME allows mobile phone applications to run on diverse devices - without recompilation. For those who don’t know, a Java ME application is delivered as a group compiled class and data files stored inside a JAR file. Additionally, a small descriptor file – known as a ‘JAD’ file - is generally provided to describe the contents of the JAR. The JAR and JAD files are collectively referred to as a “package”. In most situations, a package can be successfully delivered to devices from various vendors (ie, Nokia, Motorola, LG, Sony-Ericson, etc) without change or recompilation. When you think of the variety of mobile phones that are available, it’s amazing that it works. Vendors have gone to great lengths to implement Java ME onto their devices from the factory, and to ensure that it works correctly. I believe that this investment will continue and that Java ME will be around for a very long time. ToolsThere are many excellent tools for creating and packaging Java ME applications. Many emulators have plugins to help manage code (e.g. the eclipseme plugin for eclipse IDE). There are also as several Ant-driven build scripts (e.g. antenna and J2ME Polish). However, one tool that is a “must have” for development of Java ME applications is the Sun Java Wireless Toolkit (WTK). Indeed, it should be your first choice for compiling and packaging applications. Whilst it does not include a facility for editing code, it does include everything else that is required, including means for arranging, compiling, verifying, signing, packaging, deploying and testing Java ME applications. The standout feature of the WTK is the device emulator. This is a mobile phone reference implementation for Java ME. It is run on the development platform, provides a mock “mobile phone” on your desktop and looks something like this:
The WTK emulator greatly reduces testing time and effort. All J2ME functionality of an application can be tested on the emulator. And once an application works correctly on the emulator it can be deployed onto real devices for further testing and fine-tuning. DeploymentJava ME application deployment onto real devices is usually painless. Deploying the application over the internet - generally referred to as "Over the Air” (OTA) - is the most popular way of deploying applications to the public. However, to get an application onto a device this way, there are a few prerequisites:
Once these prerequisites are satisfied, then it’s simply a matter of starting the mobile phone browser and typing in the URL for the application software; the Java ME implementation will do the rest. It will download the application, and automatically start the install process. An alternative to deploying OTA is to download the package onto a computer, and then deploy from the computer to the mobile phone using technology such as Bluetooth. This mechanism works particularly well on Nokia mobile phones. The BadNow we’ll move onto “The Bad”. Java ME does have some problems and usually these have an impact when developing applications for the public that should run on “all” Java ME mobile phones - for example, games with some kind of network playability. In situations when the application is for a specific mobile phone model (for example, an enterprise application to be used in-house) the problems described are not an issue. This is because the application will generally run on a known set of devices, and can be appropriately tested. API VersionsCoding an application is a problem when you don’t know what the Java ME implementation on the phone will provide. If your application uses optional Java ME implementation classes that are not on the device at run time, it will either not install or not run. It’s a common trap for a developer to merrily code away on their development platform, and for everything to work correctly using their phone emulator (which is probably configured to use the most advanced Java ME specifications available). Then, when it comes time to install the application onto a real phone, it doesn’t work. Why? Well, there could be various reasons. For example, the Java ME implementation on the real phone mightn’t provide the 3D graphics API that the application uses. Or maybe the implementation doesn’t provide HTTPS- or Bluetooth-related classes. Or even worse, the phone’s Java ME implementation doesn’t provide the latest core system APIs that the application has been coded to. This is because the core, mandatory Java ME APIs essentially come in 2 flavors – MIDP 1.0 and MIDP 2.0. MIDP 1.0 is an earlier API which is found on older mobile phones. MIDP 2.0 encompasses all MIDP 1.0 functions, provides improvements in the areas of GUI and network interfaces, and is generally found on newer mobile phones. MIDP 1.0 API functions will operate on MIDP 2.0-enabled devices, but not vice-versa. The problem is that when developing applications for public use, it seems that the general philosophy is “write code using the latest specs (MIDP 2.0), and then try to retrofit it to MIDP 1.0 later, so that the application will run on as many devices as possible”. This is a flawed philosophy, resulting in a great deal of retrofitting activities for little benefit. My recommendation is to simply code your application using MIDP 2.0 APIs. While this seems like a large potential audience for your software is being cut out, there are various justifications for not coding to the older specification:
Device Network ConfigurationSetting up your phone to connect to the internet is difficult. Although internet phone configuration is beyond the scope of the Java ME specification, it is an issue that has a direct impact on whether a user can download and run your application. The most convenient mechanism for delivering applications is GPRS. However, many phones do not have GPRS configured or enabled by default. Additionally, if your application uses the internet for sending/receiving data, then this will not work either if GPRS is not working on the device. Configuring GPRS on mobile phones is complicated and tedious. Consequently, it may be beyond the capabilities or interest of the average mobile phone user. Many phone carriers provide the ability to enable and send GPRS configuration information to the mobile phone over the air (OTA). This is convenient, but does require action from the phone owner to activate (for example, they may have to call the carrier help desk, or perhaps visit the carrier web site). Anecdotal evidence suggests that it is a fairly common problem in Australia for devices to not be GPRS-enabled, but not so overseas, where mobile phones are always delivered with GPRS fully enabled and functioning. Often this problem becomes apparent during development when you may want to demo an application. If the user doesn’t have GPRS enabled on their mobile phone, then it’s best to demo on your own phone - it’s just not worth the pain of trying to get them set up on the spot. Device Phone Number AwarenessAs far as I can tell, there seems to be no way for a Java ME application to reliably and consistently determine the phone number of the mobile phone that it’s operating on at runtime. Consequently, identifying a particular user to the application is difficult. Instead of just using something concrete - like the phone number of the device - additional coding is necessary at both the application and deployment level to provide identification features. API FragmentationMany Java ME specifications are completely optional; a vendor can choose whether or not to implement them on a phone. If your application requires an optional API but is installed on a phone without this capability, then the installation will either not install, or worse, install and not run (depending upon the device). So if your whiz-bang calculator application happens to have a splash-screen which uses the optional 3D package, then don’t expect everybody to be able to run it, even if it uses just the core API for everything else it does. A workaround is to deliver packages based on functionality, but this can get very complicated, very fast. For example, consider an application which delivers some base functionality, but also uses the optional 3D and Bluetooth APIs. Different physical packages could be built which exclude particular functionality, meaning that you could end up with the following packages:
So suddenly your application can come in at least 4 different flavors, or even more if your application uses other optional APIs. And you have to manage and maintain them appropriately. Even worse, the end user has to try to figure out which of these applications are suitable for installation on their mobile phone. Installing the “wrong” package will result in an application that doesn’t work. And to add insult to injury, the user may have paid for the network traffic of downloading the wrong package! My recommendation here is to make life easier by coding the application to just deliver base functionality. If the optional API’s are absolutely required, then include them, but make it clear to users that specific functionality is required of their device and that your application may not run on all mobile phones. The UglyFinally, we’ll cover problems with Java ME that are particularly gruesome. Usually their impact is beyond the control of the developer or the mobile phone user. Indeed, these problems are usually ultimately caused by the big players – phone carriers, software distributors and certification houses. Beware! Code Signing CertificatesAged or missing root security certificates on a device can mean that your signed application will not be installed. First, some background: having a signed application means that the application is “trusted”. When the application is downloaded OTA, the certificate is checked against the device’s root certificates. If it cannot be verified against one of these, the application will not be installed. Furthermore, a user can theoretically track down the entity responsible for the application via a certificate authority which knows the entity’s true identity. Certificates must be purchased from such an authority and are fairly costly. Signed applications enjoy privileged permission status in Java ME. For example, a trusted application could connect (or be configured to connect) to the internet without explicit user confirmation. Non-signed (or untrusted) applications theoretically do not enjoy this privilege. Unfortunately, many phones do not have up-to-date certificates from all major certificate authorities. So when the Java ME implementation on such a phone tries to verify the application certificate against its root certificates, it may be blocked from installing. The solution: if you can possibly get away with it, don’t certificate-sign your application. In other words, don’t use a certificate at all. Your application will not be signed but at least it will be able to be installed. Code signing is of dubious value - it often limits the number of handsets that your application will work with for little real benefit. One final note: those sections of the Java ME specification concerning management of trusted and untrusted applications are flexible - it’s up to the implementation to decide how to implement security permissions. Furthermore, various modern mobile devices now have the ability to configure specific applications to enjoy greater-than-default privileges. For example, an untrusted application can be configured by the end user to allow http connections by default, without user confirmation. HTTPS CertificatesAged or missing root security certificates on a device can also mean that your signed application may not be able to successfully establish a HTTPS connection. When making HTTPS connections, a Java ME implementation must verify the certificate of the remote site against its root certificates. But what happens next depends upon the implementation. Newer phones may allow you to override and continue (just like in your PC browser, with a message like “this site certificate cannot be verified, continue?”). Other implementations (usually older phones) simply do not allow the connection to proceed any further. The solution to this problem? If you can get away with it, use HTTP instead of HTTPS. HTTPS may provide little real value and needlessly limit the number of handsets that your application will work with. If it is absolutely mandatory that data sent/received to the device is encrypted, it may be better to “roll your own” encryption. There are many examples and frameworks available on the internet, for example, the Bouncy Castle Lightweight API. Carrier Locks out FunctionalityAnother Java ME “ugly” that we’ve seen is that some devices are tied to the phone carrier, and have functionality disabled. A specific example that springs to mind is the BlackBerry 8700g. Normally, this device is fully capable of providing GPS (satellite positioning) co-ordinates to Java ME applications running on it - it's documented in the user guide. However, 8700g’s that I have used that were purchased through Telstra (a major Australian telecommunications company) were unable to provide this functionality. Even the GPS configuration options can no longer be found. Why? Well, you’ll have to ask them! Java VerificationA final nasty that your application may have to undergo is a costly verification in order to make it available to the public. Applications can be sold publicly (on the internet) by a mobile provisioning service that collects payments for distribution. Some of the major services require the application to undergo some sort of application verification before they will distribute it via their web site. This is fairly expensive, and the developer may not wish to pay for it. In that case, the provisioning service will not distribute the application. In our opinion, whilst independent testing is definitely of value, it should not be forced. However, in the meantime, you should at least brace yourself for the possibility. ConclusionsIn this article I’ve explained the good, bad, and just plain ugly features of Java ME. First, we saw that "the good” included:
Next, I explained how "the bad” concerned problems of API versioning and fragmentation, and the associated difficulties of configuring mobile phones for internet access. Finally, we saw how "the ugly” usually concerned the runtime environment (devices and carriers) and centered on security certificates, locked-out functionality and Java verification. In my opinion the “good” of Java ME far outweighs both the bad and the ugly. There are alternatives to Java ME, but if you want to deliver robust applications to the widest possible mobile phone audience, it’s the best technology to go with. The Java ME community is active and exciting. Furthermore, it’s a technology that is both a de-facto standard and rewarding to work with. Java ME – a little bit of bad, a touch of ugly, but mostly good. |