C H A P T E R  6

Porting Strategy

This chapter is a high-level overview of the porting process and includes strategies to help you through the porting process. It breaks the porting process into a series of discrete steps and provides a description and rationale for each step. In addition, each step describes how to find more detailed information about each part of the porting process.

The porting process cannot be rigidly defined and the steps included here are not the only path through the porting process. Many decisions you make as your port progresses depend on the stability of your platform at the time you are porting the Java Wireless Client software. These decision points are highlighted where possible.

In general, you will follow these steps, which are discussed in more detail in the rest of this chapter:

1. Build for one of the reference platforms. This verifies that you have most of the right tools available and understand at a high level how the build works. You get to practice building with a fully functional set of source code before starting the port to your own device. Consult the Build Guide for instructions on building Java Wireless Client software.

2. Run TCKs on the reference platform build. Configuring and running TCKs is not a simple task, so doing this on a reference platform build gives you some practice on a working build before you start porting to your own device.

3. Set up your device development system. You might need another compiler to build for your device. In addition, you need to understand or create mechanisms for moving executables to your device, running them, and interacting with them.

4. Build stubs for your device. This step enables you to perform a complete build for your device without having ported any code. It also serves to verify that your device development system is up and running.

5. Port each component. This is the hard part. As you complete each component, run tests to verify your implementation.


Build the Software on the Reference Platform

The first step in the porting process is to build and understand a Java Wireless Client software reference platform port.

By building a source base that is known to build correctly and to run on a specific platform, you can become familiar with the source base and the process required to build the software. Because you can observe its behavior in a debugger while you work on your port, the reference port is extremely helpful when you start to port the software to your device.



Note - Be sure to document the process as you go so that it can be replicated by other developers in your organization.



The Build Guide describes how to build a reference platform port.


Run TCKs on the Reference Port

To demonstrate that your port conforms to the relevant specifications and is compatible with other versions of the software, you must run the applicable Technology Compatibility Kits (TCKs) on the finished product. The task of configuring the TCKs and successfully running the tests is not a simple one. For that reason, run the TCK on the reference port before you attempt to run it on your ported version of the software. By first running the TCK on the reference implementation, you know that all the tests run successfully and that no tests fail. If any tests fail, it is probably because you configured the test environment incorrectly.

After you successfully configure and run the TCK on the reference port, it is much easier to run the test suite on your ported version of the software.

Be sure to document the process as you go so that it can be replicated by other developers in your organization.

You must run the current applicable TCK for each portion of the Java Wireless Client software that you port.



Note - As delivered, the Java Wireless Client software does not include all of the software components necessary to pass all of the TCKs. For multimedia (both MMAPI and AMMS), 3D graphics, and OpenGL® ES in particular, you must integrate third-party components before the corresponding TCK tests are passed.




Set Up and Configure Your Device Development Environment

To be able to port efficiently, you must set up your development environment so that you can download programs and data into your device and receive debugging information from the device. Specifically, your environment must enable you to do the following tasks:

Requirements differ depending on your development environment. For example, if you develop your port on a software emulator that runs on a computer system, you might be able to accomplish this by simply copying files into the emulator and using printf statements to write to the console. On the other hand, if you develop on a simulator board, a development board, or directly on the device, this can be more complicated because it has no console. However, a serial port through which (with extra work) you can get output might be available.


Port the JavaCall API

If you're going to use the JavaCall API, then PCSL, CLDC, MIDP, and the optional APIs are already finished because they are already ported to the top of the JavaCall layer. Your job is to implement all the glue between the bottom of the JavaCall layer and the native OS.

All your porting occurs at the JavaCall layer, which is described in this section.

The JavaCall API is divided cleanly into modules. The recommended porting order looks like this:

1. Implement module group 1:

2. Implement module group 2:

3. Milestone: ability to run basic MIDlets and Application Management System (AMS) Environment.

4. Implement module group 3:

5. Implement module group 4:

6. Milestone: ability to run TCK Framework and begin Java platform testing.

7. Implement module group 5:

8. Implement module group 6:

9. Implement Optional APIs.

 


Port PCSL

If you are not going to use the JavaCall layer, you will need to port PCSL, CLDC, MIDP, and optional APIs. The rest of the sections in this chapter describe these porting steps.

PCSL is the Portable Common Services Library. It is portable in the sense that it defines a set of interfaces that higher-level implementations use. It is common in that both MIDP and CLDC implementations use the interfaces defined by PCSL. This facilitates porting and maintenance because you only have to implement the common interfaces once.

Implement PCSL early in the porting process for these reasons:

The following table describes PCSL subsystem functionality.


TABLE 6-1 PCSL Development Subsystems

PCSL Subsystem

Description

Types

The types subsystem contains platform-specific definitions of primitive types and constants. The primitive types must be defined according to the definitions of the KNI primitive types in the KNI Specification. For example, define jboolean as the platform-specific unsigned 8-bit type.

Print

The print subsystem (an implementation of JVMSPI_PrintRaw) is generally the best subsystem to port first. For example, a working print subsystem provides you with the means to get output from the device by funneling all print activity through the device's serial line or to a memory buffer.

Memory

The next subsystem that you generally port is the memory subsystem. The development memory subsystem differs from the other subsystems in that it can actually be used in production. The development version of the PCSL memory subsystem allocates memory from a single, large chunk of memory provided by the device's native memory system. It also provides some debugging features.

The requirements of your device dictate whether you continue to use the PCSL development memory system or implement a native version in the production version of the system. More information about this is available in Chapter 8.

File system

PCSL provides a simulated file system that is useful during the porting and development process. It implements the file system interfaces but stores files in RAM. This means that data stored in this simulated file system does not persist after power cycling.

Note that the PCSL development file system is extremely useful during development for testing and debugging purposes, but is unsuitable for production implementations.

Network

Basic networking is implemented using Socket-over-Serial (SoS) functionality. This is extremely useful when doing network development on a device that does not have radio or Ethernet networking capability. To simulate a network, SoS gathers the bytes from packets, adds a special header, and redirects them to the serial port. The serial port is connected to a computer system on which an SoS server is installed. The SoS server opens a real network connection to a server on the LAN, then converts the SoS packets to network packets and sends them on.

Note that the PCSL SoS networking functionality is extremely useful during development for testing and debugging purposes, but is unsuitable for production implementations.

String

The string subsystem defines an opaque pcsl_string type and provides basic string operations. To port this subsystem, you must first choose an internal representation for pcsl_string.

After you select the internal representation, implement all string manipulation functions declared in the interface of the PCSL string library.

The reference implementation provides the pcsl_string definition based on UTF-16 encoding.


When you build PCSL, be sure that the self tests are linked and then run the tests to verify that the functionality works. Note that the test results must be available though the output functionality described in Set Up and Configure Your Device Development Environment.

For more information about porting PCSL see Chapter 8.


Port CLDC HotSpot Implementation

The process for porting CLDC HotSpot Implementation is described in detail in the CLDC HotSpottrademark Implementation Porting Guide. This section describes some strategies to consider while porting CLDC HotSpot Implementation as part of your Java Wireless Client software port.

Enable PCSL

CLDC HotSpot Implementation has build options that allow it to run alone, or on top of PCSL. Be sure you enable the option in CLDC HotSpot Implementation that builds it with PCSL. See the Build Guide for details.

Normal and Slave Modes

At this point in the porting process, it might be appropriate to consider whether you will run the Java Wireless Client software in normal mode or slave mode.



Note - Normal mode is often referred to as master mode because of its relationship to slave mode.



This decision is based on which mode works best with your device. Normal and slave modes are discussed in Chapter 10.

If at this point in the process you understand the following about your system, you can make the decision whether to use normal or slave mode:

If these issues are not yet clear, you can postpone this decision and use the system in normal mode (the default) to run simple test programs. In this case, revisit the decision about whether to use normal mode or slave mode when you implement the MIDP event mechanism later (in Port MIDP).

Test Programs

To test that the VM is working at least minimally, write some simple tests in the Java programming language, then download the class files and run them on the device.

The first test program must use only the VM facilities and not any part of the MIDP APIs which are more complex to port. The typical small example is something that prints "Hello, world!" to standard output. Most devices do not provide a standard output, but the VM has a porting interface (JVMSPI_PrintRaw) that is called to handle output sent to System.out. For example, it could send the output to a serial port, but it could also put the output into a memory buffer, draw something on the screen, blink an LED, and so on. Anything that verifies that some Java bytecodes are executed by the VM will work.

ROMize the program class files along with the VM and Java platform libraries you create during the porting process. Because the ROMizer allows classes compiled from the Java programming language to be linked directly in the virtual machine, it greatly simplifies access to the test programs. See the CLDC HotSpot Implementation Porting Guide for more information about this process.

At this point in the porting process, you can run a test program from the command line. Write a program that implements the method public static void main(String args).

Compile it with the javac and preverify commands, then run the command. For example:

% cldc_hi JVM_options classname args


Implement Native PCSL Functionality and Expand Testing

If you have working implementations of the underlying native subsystems on your device, this is a good time to connect them to PCSL. If any or all of your native implementations are not yet ready, or are too unstable, you can postpone some or all of this work until later.

Note that you can implement the native versions of the three PCSL subsystems (memory, networking, and file system) independently. You can also run with a mixture of development and native subsystems. After you port, be sure to run the PCSL self tests to confirm that the implementation works.

If you continue to use the development implementations, you must be more and more creative about working around the limitations of the development implementations. For example, if your file system is not implemented, you can place files into ROM or create a utility that preinitializes the RAM file system with files.

If possible, this is also a good time to expand testing by running test programs from outside of the ROM image (for example, from the device's native file system). If for some reason it is not possible to implement native file system functionality at this point, you can run the programs by preloading them into the generic PCSL RAM-based file system and then have CLDC HotSpot Implementation load them from there.


Initial TCK Testing

Once you successfully run your test programs, consider further expanding the scope of your testing by running the TCK. Although setting up the TCK is not a simple process, it is an excellent way to identify problems with the port. The work you did in Run TCKs on the Reference Port simplifies the process for you now. Replace the reference port classes with your classes and then run the TCK. Some changes in the configuration might be required.

If you have the native networking and file subsystems working through PCSL, run the tests as described in the Java Technology for the Wireless Industry TCK User's Guide. If native networking is not yet available, you can use the PCSL development implementation (SoS). If the file system is not yet available, you can use the RAM file system. See the Java Technology for the Wireless Industry TCK User's Guide for more information about running the TCK.


Port MIDP

Porting MIDP is best done in small, incremental steps. The steps described in this section are provided in the order that experience shows works well.

Build MIDP

The MIDP source tree shipped with Java Wireless Client software includes "stub" implementations of the porting library that you use to implement your port. You can use the stub files to create a source tree and build it successfully without modifying the stub files. Create a source tree for your platform based on the distribution source tree, including makefiles and libraries, and substitute the stub files as appropriate.

The distribution source tree builds on the Linux desktop using the Linux development environment. The best first step is to get the source tree to build with the stub files using the Linux desktop development environment. This is the simplest way to determine if the stub files are organized correctly. After you successfully build the source tree, the next step is to build the stub source using the cross compiler for your device.

Normal and Slave Mode Event Handling

At this point it is necessary to consider how events are delivered to MIDP from outside the system. Control flow is the central issue regarding event delivery. The following questions highlight the issue:

This topic is closely related to the decision about whether to run the VM in normal mode or slave mode, as discussed in section Normal and Slave Modes. A complete discussion of the issues is in Chapter 10.

MIDP contains alternative modules that start the VM and implement event processing differently depending upon which mode you choose. Once you make the decision whether to use normal mode or slave mode, configure the MIDP build so that the appropriate module is used.

Run a Test MIDlet

To verify that MIDP has been built and ported properly, try running a simple test MIDlet. The MIDlet should do something extremely simple, such as print a message and exit. It is important for the MIDlet to exit on its own, because there is no way for the user to interact with it yet. A simple "Hello, MIDP" test MIDlet is shown in CODE EXAMPLE 6-1.


CODE EXAMPLE 6-1 "Hello, MIDP" Test MIDlet
import javax.microedition.midlet.MIDlet;
 
public class Hello extends MIDlet {
	public Hello() {
			System.out.println("Hello, MIDP!");
			notifyDestroyed();
	}
	public void startApp() { }
	public void pauseApp() { }
	public void destroyApp(boolean unconditional) { }
}

The simplest way to compile and package this MIDlet is to use the Sun Java Wireless Toolkit. You can use the toolkit to verify the correct behavior of the test program before you run it on your device. After packaging the test application, copy the JAR file to your device, then run it with the following command:

runMidlet -classpathext Hello.jar internal Hello

The -classpathext argument extends the class path to include the JAR file. The suite ID "internal" indicates that the MIDlet class is found in the ROM image or in the class path. Finally, "Hello" indicates the class name.

If it is not possible to load JAR files from the file system, you can add MIDlet classes to the Java Wireless Client software build and have them included in the ROM image. You can run these classes using the following command syntax:

runMidlet internal Hello

If you run MIDlets directly from the ROM image, the -classpathext option is not required.

As you bring up the ports for the various functional areas below, you can write simple, specific test programs and then run them in this fashion.

Graphics, Image and Fonts

This is the point in the porting process to implement the graphics, image, and font systems. Java Wireless Client software provides PutPixel technology to simplify the process of getting these functions up and running. While you are porting, use PutPixel technology as a quick way to get running. Then either replace it with a port to your platform's native resources as described in Chapter 13, or use it directly in your product.

For more information see Chapter 12.

User Input Handling

The following steps describe how to implement user input handling functionality:

After you complete these tasks, create a test application that uses Canvas and GameCanvas and that can receive key and pointer events and invoke abstract commands.

High-Level UI

Determine your strategy for porting UI components. You can base your implementation on Java technology (AUI Technology software) or on native platform UI components.

Porting to AUI Technology software (using the default skin) is straightforward, as it uses only graphics, images, key and pointer events, and commands. After the AUI Technology software is working using the default skin, you can start using custom images to create your own custom skin. For more information, see the Skin Author's Guide to Adaptive User Interface Technology.

Porting to native platform UI components is more involved. The LCDUI classes in javax.microedition.lcdui are implemented in terms of the "LF" interfaces (the look and feel layer). The implementations of these interfaces (by convention suffixed with LFImpl) bridge the gap between the Java technology and the native platform UI component set. Because native platform UI components sets vary widely, you must create your own set of native functions so that the LFImpl Java classes can communicate with the native UI component implementation.

Determine the events that are allowed to pass into CustomItem and the traversal model used for CustomItem.

For more information, see Chapter 16. After you complete these tasks, create a test MIDlet that uses a Form that contains an arbitrary set of UI components. Switch among high-level Displayable objects such as Form, Alert, TextBox, and List.

Networking

Decide on the set of network protocols the system supports. The HTTP protocol is required, while others such as HTTPS, sockets, server sockets, datagrams, and secure sockets are optional. Configure the system to include the right set of protocols.

PCSL supports some of these protocols already. For others, you must port to the MIDP porting layer.

After you complete these tasks, create a test MIDlet that communicates over the network.

RMS

By default, RMS is implemented using file-based interfaces. If you have a fully functional PCSL file library, RMS comes up quickly. If you are still running PCSL with the development implementation of the file system, this is a good time to implement the native version. Although the RMS works with the RAM file system, it is best to port it using a fully functional and persistent implementation.

For more information, see Chapter 17.

After you complete these tasks, create a test MIDlet that creates, lists, and destroys record stores and can insert, delete, update, and enumerate records within a record store.

AMS and System Integration

The AMS (application management system) is a set of functions responsible for the following services:

You can base your implementation on Java technology or on a native system.

A Java AMS requires that the following subsystems be implemented:

Once these subsystems are implemented, Java AMS is fairly straightforward to implement.

With a native AMS, the user interface for these functions is presumed to be implemented in native code, outside of MIDP. The system calls MIDP native functions to perform tasks such as installing, updating, removing, and viewing information. The VM must not be running when these tasks are performed.

To invoke Java programming language applications from a native AMS, start the VM and pass it parameters to invoke the named MIDlet. While the VM runs a MIDlet, the rest of the system must not be allowed to change the state of installed MIDlets (you cannot update a MIDlet while one is running).

Run the MIDP TCK

At this point, you are ready to run the TCK to ensure that the system is running correctly and to find any problems. Before you run the TCK, you must implement the MIDP AutoTester. The AutoTester is a MIDlet that installs and runs sequences of tests without user intervention.

For more information about the AutoTester, see Chapter 19. For more information about running the MIDP TCK, see the MIDP Technology Compatibility Kit 2.0a User's Guide.

Run the Java Device Test Suite Software

The Java Device Test Suite software is a comprehensive set of functional tests for wireless devices. It includes deep functional testing for various Java ME technologies. At this point in the porting process it is a good idea to run the Java Device Test Suite software test suites for MIDP. The Java Device Test Suite software also includes tests for several optional packages. Run the Java Device Test Suite software test suites for these optional packages as you port them later.

Enable the Multitasking Feature

Now that you have a fully functional MIDP implementation, it is time to enable the multitasking feature. Rebuild the system and set the build option USE_MULTIPLE_ISOLATES to true. If you are using the Java AMS, bring up the system and install several MIDlets. While running a MIDlet, try to return to the application manager screen by pressing a special key such as the Home key. At this point, you can switch to a running application or you can invoke a new one.

Next, decide on multitasking policies, and tune the resource management policies based on the capacities of your device. See the Multitasking Guide for more information.

Once the multitasking feature is enabled and is running well, test its quality using the Multitasking Quality Test Set (Multitasking QTS). The Multitasking QTS is a set of tests that can be added to the Java Device Test Suite software. See the Multitasking Quality Test Set Guide for information about how to set up and run these tests.


Port the Optional Packages

After you port the core functionality, you can port any of applicable optional packages that are shipped with Java Wireless Client software. See the Optional Packages Porting Guide for more information.