Our BlackBerry Development Environment

We have been hired to port an iPhone/Android app to BlackBerry. The prospect of developing a BlackBerry app is painful for us for several reasons:

  1. The only IDE plug-in is for Eclipse. (We prefer IntelliJ.)
  2. The BlackBerry simulator runs on Windows only. (There is an Eclipse plug-in for the Mac but, actually running the application under development requires either a tethered BlackBerry device or a Windows machine to run the simulator.)
  3. The BlackBerry platform is based on Java ME. Consequently,
    • the compiler supports Java language features only up to version 1.3,
    • many useful classes, including java.util.ArrayList, java.util.HashMap, and all of java.lang.reflect are not available, and
    • some classes have fewer methods than their Java SE counterparts. For example, the Object class in the BlackBerry API doesn’t have a finalize or clone method. StringBuffer does not have indexOf or replace. (The Java ME runtime library is a very small subset of the standard Java SE runtime library.)

The third limitation is by far the most painful because it prevents us from directly using the “back-end” code we wrote for the Android application (which uses generics, annotations, Google commons, and the Google Guice dependency injection framework).

We found several techniques to improve our BlackBerry development process. Specifically, this article discusses

Development Environment Configuration

We found several articles describing how to write, compile, and run BlackBerry apps using various combinations of MacOS, Eclipse, IntelliJ, Ant, and wine (or some other VM). None of them worked exactly as described; but we were able to find a development process that worked reasonably well.

We used

  1. the BlackBerry 6.0 development environment,
  2. bb-ant-tools, and
  3. a windows machine running an ssh server (we use cygwin).

We were also able to get the BlackBerry simulator running smoothly in Parallels 6 running Windows 7.

Environment Configuration:

  1. Make sure the Windows machine has Java 6. (The simulator’s networking component, MDS, won’t run on Java 5.)
  2. Install the BB 6.0 development environment on the windows machine. (By default, it will try to install itself in C:\Program Files\Research In Motion\BlackBerry JDE 6.0.0. This will work, but choosing a path with no spaces will make your life easier.)
  3. Copy the core BlackBerry development components to the Mac:
    1. Create a directory called BlackBerryResources on the Mac.
    2. Copy the bin and lib directories from the BlackBerry JDE on the Windows machine into BlackBerryResources.
    3. Obtain a copy of preverify that will run on the Mac. There are several options:
      • The Eclipse plug-in for Mac contains a version built for the PowerPC. It runs fine on an Intel-based Mac with Rosetta. Warning: The Eclipse plug-in is very large (although you can delete it after you’ve extracted preverify).
      • mpowerplayer also comes with a PowerPC version of preverify. Download the SDK and look in mpp-sdk/osx/preverify. The benefit of getting preverify from mpowerplayer is that it is a much smaller download.
      • The MOTODEV SDK from Motorola contains an Intel-based version of preverify. Open the .dmg and look in launchpad/JMESKD/bin. You must be a MOTODEV member to download the SDK.
  4. Download bb-ant-tools. Unzip the folder and move bb-ant-tools.jar into $HOME/.ant/lib.

Set up your IntelliJ project like this:

  1. Create a “regular” Java project.
  2. Set the JDK to “No JDK”. (This prevents you from accidentally using classes that are not part of the BlackBerry API.)
  3. Set the language level to “1.3”. (This prevents you from accidentally using any of the features that make Java remotely useful.)
  4. Cry.
  5. Add a project library. Press the “Attach Jar Directories” button and select BlackBerryResources/lib
  6. Add an Ant build file:
    1. Copy build.xml into the root of your project.
    2. Click the “Ant Build” tab at the far right.
    3. Click the ”+” button.
    4. Select build.xml.
    5. Click the “properties” button. (It is 6 buttons to the right of the ”+”.)
    6. Select a JDK for Ant. (This will not change the project’s JDK.)

Now, to compile the project you can double-click on the “build” target in the Ant window. To actually run the project, however, requires Windows.

Launching the Simulator

To launch the simulator

  1. Open a Command Prompt in Windows. (In Windows 7, run the Command Prompt as an administrator.)
  2. Go into the MDS directory on the Windows machine and type run.bat. (MDS handles the networking for the simulator. If your app doesn’t require network access, you don’t need to run MDS.)
  3. Go into the simulator directory and type fledge.exe

To run an app in the simulator,

  1. Copy the .cod file into the simulator directory. (The copy_to_simulator task in the appended Ant build file will do this for you if you set up the simulator.* variables.)
  2. Reset the simulator. (Select File -> Reset from the menu.)

In theory, we should be able to load a new app into the simulator without resetting it; but, we haven’t been able to get that feature to work. Resetting the simulator takes between 15 and 60 seconds. Just think: Given a developer costs about $100/hr, it costs the customer between $.40 and $1.60 every time somebody needs to re-launch the app!

External Libraries

Using external libraries (i.e., .jar files) is not difficult provided

  1. the bytecode is Java 1.3 compatible (i.e., was compiled with the source -1.3 flag.), and
  2. all dependent classes are available on the BlackBerry.

To use the external library, run preverify on the .jar file, then bundle the resulting output with the app. preverify verifies that the code meets the Java 1.3 requirement and that all dependent classes are accounted for (either in the .jar file or the classpath). It then produces a new .jar file to be used with the app. Make sure that those items in the classpath that are not part of the BlackBerry API also get loaded onto the device.

Run preverify from the command line as follows:

preverify will place a preverified copy of externalLib.jar in output_dir. Notice that you must explicitly list net_rim_api.jar (BlackBerry’s class files) in the classpath.

The BlackBerry Support Forums suggest that it is possible to take a preverified .jar, build it into a .cod file, and install that library separately from the application’s .cod file; however, we were never able to get the external .cod file properly loaded into the simulator so that our application could reference the external code. Instead, we had to bundle the external library with our application’s .cod file. The example below shows how we added external .jar files to our Ant task. (rapc BlackBerry’s java compiler.)

Java 1.3 Limitation

It is possible to use “modern” Java code in a BlackBerry application. Retrotranslator can convert Java 1.5 bytecode into Java 1.3 compatible bytecode. This allows developers to

  • use generics and (some) other Java 1.5 and 1.6 features when writing apps, and
  • use some external libraries, even if they can’t be compiled at the Java 1.3 level.

However, Retrotranslator can’t make every library run on BlackBerry. For example, a library that uses Java collections won’t run on BlackBerry unless the developer also provides an implementation for java.util.ArrayList and other missing classes. A library that uses reflection probably won’t run at all. Watch for hidden uses of reflection including annotations and calls to clone. We tried extracting java.util.ArrayList and other seemingly simple Java collections classes from rt.jar and running them through Retrotranslator. It turns out that these classes all have one or two references to classes that are not present in the BlackBerry API. These missing classes don’t bother Retrotranslator, but they cause problems later when running preverify. Similarly, we found that adding instance variables to enums generates references to clone, Class.getComponentType, and a couple other items not present in the BlackBerry API.

Some classes, including StringBuffer have added methods between Java 1.3 and Java 1.5. Avoid using the newer methods. Retrotranslator does have a “backport” feature that provides an implementation for new methods; however, this replacement code sometimes uses classes and methods not available in the BlackBerry API.

It is possible to run Retrotranslator from the command line; but it is much easier to build an Ant task:

Hints and Warnings

Here are some things we learned the hard way:

  • If preverify reports “Illegal type in Constant Pool”, then you probably compiled something with a compliance higher than 1.3
  • We ran into two issues when trying to use wine to run preverify
    1. You can’t specify multiple jar files on the classpath. (I suspect it is a conflict between UNIX using ‘:’ to separate items and Windows using ‘;’.)
    2. preverify’s output is a .jar file. The problem is that the Windows version uses ’\\’ instead of ’//’ to separate directories.
      (There are probably solutions for both issues; but, because there are already versions of preverify that run on the Mac, we didn’t spend much time getting the windows version to work in wine.)
  • If a class is missing a dependency, then rapc may issue a warning and make a .cod file without the offending class. The result is a NoClassFoundException at runtime.
  • To open a network connection, you must have the MDS server running.
  • To run the MDS server in Windows 7, you must run the Command Prompt as an administrator.
  • The BlackBerry simulator does not support WiFi. Any network connections come from the MDS server.

Sample Ant build file