Automate the build process of your J2ME project with Antenna

by Matthew Phillips

Introduction

I think that most people would agree that Ant is a wonderful build tool for Java applications. I don't always use it, but I try to. If you aren't using Ant and would like to learn how, check out Thomas Paul's article in the March, 2002 newsletter. If you are not convinced of it's usefulness, check out Frank Carver's series of articles on building Small and Simple Web Applications - the Friki way (see the links at the end of this article). I'll wait here.

If you are still here or have returned, then you may be wondering how this all applies to that J2ME project that you are working on. If so, then I'd like to introduce you to Antenna. All those nice conveniences that the Sun Wireless Tool Kit (hereafter referred to as WTK) provides can be done easily from your Ant build script.

Integrating the WTK into your build

Antenna introduces several Ant tasks that perform key functions of the WTK. Antenna relies on the WTK to do the brunt of the work, so you will need to have that installed. As with all optional Ant tasks, you need to let Ant know about them in your build file. Fortunately Ant makes this easy for you:

build.xml

<?xml version="1.0"?>

<project name="J2ME" default="build" basedir="." >
    
    <property name="wtk.home" value="c:\wtk"/>
    <taskdef resource="antenna.properties"/>

As I wrote before, Antenna relies on the WTK to provide the underlying functionality. It does this by using the wtk.home property to find where you have the WTK installed. Antenna defines all tasks in a file called "antenna.properties", which is in antenna-bin-0.9.11.jar. Ant will know what it needs to about the Antenna tasks after you add antenna-bin-0.9.11.jar to your Ant distribution's lib folder.

Automating your jad file

The WtkJad task writes your *.jad and manifest files so that you don't have to. It looks like this:

WtkJad

    <target name="make.jad">
        <wtkjad jadfile="bin/${midlet.name}.jad"
                jarfile="bin/${midlet.name}.jar"
                manifest="bin/MANIFEST.MF"
                name="${midlet.name}"
                vendor="${company.name}"
                version="1.0.0" >

            <midlet name="TinyClass" class="TinyClass" />
            <midlet name="TinyClass2" class="TinyClass2" />
            <midlet name="TinyClass3" class="TinyClass3" />

            <attribute name="districtNo" value="378" />

        </wtkjad>
    </target>

The target has several useful properties. The jadfile property, which is the only required property, tells the WTK what to name your jad file. The jarfile controls the values of the MIDlet-Jar-URL and MIDlet-Jar-Size properties in the jad file. The name property controls the name of your MIDlet suite. Vendor and version controls the jad properties of the same name. The manifest property controls the name and location of the manifest file.

The two elements of the wtkjad task are the midlet and attribute elements. The midlet element allows you to define each MIDlet in your suite. I've shown the name and class attributes, but there is also an icon attribute if you would like to define an icon as well. The attribute element allows you to define any other properties that need to be defined in your jad file. Running the above task will result in the following jad file being built for you:

mysuite.jad

MIDlet-Jar-URL: mysuite.jar
MIDlet-Jar-Size: 1791
MIDlet-Name: mysuite
MIDlet-Vendor: maphillips
MIDlet-Version: 1.0.0
MIDlet-1: TinyClass, , TinyClass
MIDlet-2: TinyClass2, , TinyClass2
MIDlet-3: TinyClass3, , TinyClass3
districtNo: 378

Compile and Preverify

The wtkbuild task extends Ant's javac task and adds a few properties to aid with your J2ME code. One of the big conveniences of this task is that there is no need to add midpapi.zip to your classpath. The task does that for you automatically. Another important, but optional, property is the preverify property. If you set this property to true, then the preverify process will run after your code is compiled. There is also a preverify task and a preverify property of the package task (explained later) so you have several points in which you can have the preverification occur. The wtkbuild task looks like this:

mysuite.jad

    <target name="compile" depends="init">
        <wtkbuild srcdir="src" destdir="classes" preverify="true" />
    </target>

Packaging your code

The wtkpackage task extends Ant's jar task and gives you a little more control over the packaging process. As stated previously, you may preverify during this task, but since we did that during the compile process, there is no need to here. It needs to know the directory you want to jar, the name of the jar file, and the name of the jad file. If you have any external libraries to include, you may do so with the libclasspath attribute. You may also run an obfuscator during the package process, but we'll save that for a separate task. The wtkpackage task looks like this:

mysuite.jad

    <target name="package" depends="compile, make.jad">
        <wtkpackage jarfile="bin/${midlet.name}.jar"
                    jadfile="bin/${midlet.name}.jad"
                    basedir="classes"
                    manifest="bin/MANIFEST.MF"
                    preverify="false"
                    libclasspath="lib"
        />
    </target>

Running the emulator

Running your MIDlet suite is made incredibly easy with the wtkrun task. It needs to know the name and location of the jadfile. It will use the default device of the WTK, but you may also use the device attribute to control this. The default behavior of this task is for Ant to pause while the emulator is running. That will allow you to see anything that the emulator writes to System.out or System.err. If you don't want this behavior, you can set the wait attribute to false. A simple wtkrun task looks like this:

mysuite.jad

    <target name="run" depends="package">
        <wtkrun jadfile="bin/${midlet.name}.jad" device="DefaultColorPhone" wait="true"/>
    </target>

Obfuscation

When you are ready to deploy your code, you may want to obfuscate it. The wtkobfuscate task will take care of it. It can use either the RetroGuard or ProGuard. ProGuard is the default, but you may use the obfuscator attribute to specify which to use. In order for this task to function properly, the jar file for the obfuscator you choose needs to either be in the WTK's bin folder or on your class path. The task looks like this:

mysuite.jad

    <target name="obfuscate" depends="package">
        <wtkobfuscate jarfile="bin/${midlet.name}.jar" obfuscator="retroguard"/>
    </target>

Conclusion

Antenna has made my development life much easier. I hope this introduction will make yours easier as well. The Antenna web site has valuable information to make the tool even more useful.

Small and Simple Web Applications - the Friki Way
Part 1
Part 2
Part 3
Part 4
Part 5
Part 6