From the point of view of the Symbian OS
architecture, the Java ME subsystem is a replaceable component that
Symbian OS licensees can extend, customize or replace altogether.
Additionally, the Java ME subsystem, as a whole, is a native application
just like any other standard native application (although it is a very
large application) that is shipped with the device, burnt on the ROM.
So the Java ME subsystem is a native application that
accesses operating system resources generally through the same publicly
available APIs as any other third-party application. The only
difference is that it is a very big application. The phrase 'the tip of
the iceberg' describes quite well the Java ME subsystem as seen from the
point of view of the user of Java applications. Only a small part of
something largely hidden can be seen (see Figure 1).
Underneath every lightweight Java application, there is a very big and
highly complex engine. There is a very good reason for that. The Java ME
platform is a huge abstraction layer (composed of many internal
abstraction layers) that lets you deploy and run a 'Hello, World'
application in less than 10 lines of Java code on a variety of
completely different platforms!
The Java ME specifications define a few core logical entities (see Figure 2),
such as the application management system (AMS), the profile (MIDP) and
the configuration (VM and base classes). However, the separation
between entities is mostly logical, which leaves room for different
possible implementations.
Although we discuss only the implementation on
Symbian OS, there are other implementation models. For example, the
open-source PhoneME project
takes a highly generic and modular approach that is designed to be
easily portable to many different native platforms (e.g., BREW, Windows
Mobile and Linux to name just a few). The Symbian OS Java ME subsystem
takes a proprietary integration approach which is tightly coupled with
Symbian OS. Let's see why.
1. How Symbian OS Differs from Other Java Hosting Operating Systems
There are a few key reasons as to why the Java ME
subsystem takes a unique and proprietary approach to integration with
Symbian OS.
First, Symbian OS is an open platform and has an
existing application management model for installation and launching.
MIDP application management must be integrated with the native model
which makes any MIDP-only application management inappropriate.
Secondly, although versions of Symbian OS from
version 9 support POSIX, it is not shipped on all devices and
specifically not on devices before Symbian OS v9. The older and
deprecated stdlib layer is not complete enough to support MIDP
2.0. That would leave most of the JSR functionality to be implemented
using Symbian C++ APIs. Hiding the native Symbian C++ code under a
generic platform-agnostic C layer is also not a proper solution because
of the idiomatic use of Symbian OS services which would not fit well
with a generic C layer.
Thirdly, as an application platform, Symbian OS has a
rich set of native UI controls that are customized by different
licensees to produce a distinct and precise look and feel to which Java
applications must adhere.
These are some of the key issues that limit the reuse
of code developed for other platforms to only the VM engine and Java
packages that are implemented in pure Java. The general shape of the
Java ME subsystem architecture is therefore unique and proprietary to
Symbian OS. If at some point a legitimate question arises of possibly
being able to implement a component in a more generic way or of reusing
existing code from other platforms, please assume that it was considered
but there was a good reason to opt for a Symbian OS proprietary
approach.
2. Overview of Architecture and Main Processes
Some groups overlap in the area which they point to but imply that it
is being discussed from a different point of view. In cases where a
certain component is not included in the group definition, although it
is relevant to it, we explicitly note that it is excluded from that
group definition.
Table 1. Definitions of Component Groups
Group | Definition |
---|
Virtual machine (VM) | CLDC Configuration VM; the bytecode engine written in native code (Note: Java Configuration classes are not included.) |
MIDP layer | MIDP implementation only (Note: the underlying Configuration and VM are not included.) |
MIDP/CLDC run-time environment | Combination
of the MIDP layer, Configuration classes and VM, as seen from the point
of view of the Symbian OS architecture (Note: the AMS is not included.) |
Java ME subsystem | Combination of the AMS and the Java ME run-time environment, as seen from the point of view of the Symbian OS architecture |
Java ME platform | AMS and the Java ME run-time environment, as seen from the point of view of a hosted Java application |
Java ME run-time environment | MIDP/CLDC environment, as seen from the point of view of a hosted Java application (Note: the AMS is not included) |
Now let's take a first look at Figure 3,
which depicts the two main processes in the Java ME subsystem
implementation on Symbian OS. There are two main process types: the AMS
runs in a single native process and takes care of the lifecycle and
resource management of MIDlets amongst many other responsibilities; each
MIDlet suite executes in the MIDP/CLDC run-time environment which runs
in a separate native process.
When the user wishes to launch a MIDlet, the AMS
spawns a new child process executing the MIDP/CLDC run-time environment,
for each application suite. That is, a new run-time process is spawned
only for the first MIDlet that is
launched from the suite. Additional concurrently running MIDlets from
the same suite are executed in the same run-time process.
The interaction between the AMS and the MIDP/CLDC
run-time process is not one way. There are a few cases which require the
AMS to invoke operations in the run-time process, and other cases which
require the run-time process to invoke operations in the AMS. For
example, when a Push connection is dynamically registered, the Java
connection object will be managed by the MIDlet in the Java ME run-time
environment and the native connection will live in the AMS process. The
Java ME run-time environment will instruct the AMS to carry out the
operation of opening the connection. For that purpose, and others, there
are inter-process communications (IPC) mechanisms to allow each process
to invoke remote operations on the other process.
The MIDP/CLDC run-time environment in Symbian OS is
built from two major components: a replaceable VM that can come from
different VM vendors (e.g., Sun and IBM) and a proprietary
Symbian-developed Profile (e.g., MIDP 2.0) including the various JSR
implementations. This separation is done to get the benefit of existing
implementation reuse where possible.
There are two main insulation layers in the MIDP/CLDC run-time environment (see Figure 4).
The first is the porting layer that every VM would have, which lets it
receive basic services from the underlying operating system. The second
is a layer which insulates between the MIDP layer and the VM.
Let's discuss how common functionality and customizable functionality are architected in the Java ME subsystem.
Due to the need for different licensees to customize
various elements of the AMS and the Java ME run-time environment, both
are delivered as a series of executable files. Such a design allows
Symbian OS licensees to implement a specific variant of the
functionality by localizing changes in a designated plug-in. The AMS and
the Java ME run-time process each have one main executable (EXE) that
is built from the common functionality code, and many smaller
dynamically loaded libraries (DLLs) that are built from the variant
functionality code. To give just a few examples: the AMS has DLLs for
customization of the security module, MIDP Push modules, and so on; the
MIDP run-time process has separate DLLs for customization of the UI,
multimedia support, and so on. This mechanism allows the Java ME
subsystem to be easily adapted to different UI platforms (e.g., S60 or
UIQ) and to comply with different OEM or operator requirements.
So far, this has been a high-level overview of the
general architecture which defines the separation of logical entities
into different processes, and how the various components are built and
interact within the native environment. The following sections each
focus on a specific area and discuss it in more detail.