Automating Eclipse-based BlackBerry project with Ant

Automating Eclipse-based BlackBerry project with Ant

This blog is taking a new turn as I’m taking on a new job currently dealing with build automation for mobile development and Macintosh development.

The first project I had to deal with was automating the build for a BlackBerry application originally developed in Eclipse with Blackberry plugin.

I chose to automate the build with Ant with the help of the wonderful bb-ant-tools package.

There are a number of tutorials giving a nice overview of how this is done, so I won’t describe the basics – you can visit the following links for that:

http://www.slashdev.ca/2007/05/30/blackberry-development-with-ant-eclipse

http://supportforums.blackberry.com/t5/Java-Development/How-to-use-bb-ant-tools-with-Eclipse-without-the-Eclipse-plugin/m-p/123689

By the way, I built the whole thing on a windows 2007 VM and I did install Eclipse Galileo with BlackBerry plugin and BlackBerry Java SDK  version 4.6.0.23. I needed this to check how the project is built with Eclipse and to make sure that the changes I insert don’t mess up the Eclipse build.

Well, of course it took me some time to figure out what arguments I have to feed the <rapc> task, as the rapc command line shown in BlackBerry packaging console in eclipse doesn’t fully reveal what happens underneath.

Specifically it took me some time to translate this:

-sourceroot=C:MyProjectsrc;C:MyProject.locale_interfaces;C:MyProjectres

to this:

<src>
<fileset dir=”.”>
<include name=”src/**/*.*” />
<include name=”.locale_interfaces/**/*.java” />
<include name=”res/**/*.*” />
</fileset>
</src>

I expected rapc to be able to read the directory content by itself, but bb-ant-tools only supports feeding it the detailed file list. In my case I used generatesourcelist=”true” because we have a lot of files in our project.

BTW – this article gives you an overview of rapc command line (mysteriously undocumented by RIM).

Jad file creation

I also needed to create a .jad file (stand for Java Application Descriptor) – bb-ant-tools <jdp> task is used for that matter.Now, the Elcipse plugin builds the .jad file based on the information defined in BlackBerry_App_Descriptor.xml. Currently I just manually copied the necessary info into the build.xml, but the right way is of course to design some automation to extract these properties and thus generate the <jdp> attributes. It’s on my task list…

Another challenge I faced is that in our project the Midelt-Name was supposed to be different from the cod file name. bb-ant-tools <jdp> task (as of version 1.2.9) doesn’t support setting the Midlet-Name but automatically sets it to the name of the .cod file (it’s the output attribute of <rapc> task) . I solved this by downloading the bb-ant-tools sources from sourceforge and editing the java code to support this propery. So now I am using my own version of bb-ant-tools jar. I suggested the feature on the sourceforge tracker so it may be included in the next release.

Images

Another challenge was the images location in the resulting package. I found the best way to compare my build output with Eclipse output was by comparing the jar file which is generated by both. The problem was that in Eclipse -generated jar the images were correctly placed under /img folder with additional sub-folder hierarchy, while what rapc generated was a jar with all the resources spread flat at the root level.

this is a known issue as follows from here : http://supportforums.blackberry.com/t5/Java-Development/How-to-use-bb-ant-tools-with-Eclipse-without-the-Eclipse-plugin/td-p/123689/page/2

in fact, as one of the posts there says : “When you specify “destdir” attribute of <rapc> tag, all resources will be stored in the root folder of the output file without considering the directory structure you have in your project.”

So I tried not specifying the “destdir” attribute, which resulted in .jar being created in project root folder packaging all the directories specified in <rapc>-><src> nested element. This did presereve the folder hierarchy which gave me a hint.

So in the end what I did to correctly package the resources was this:

  • Copy the /img tree to the .cod output folder prior to <rapc> task

<copy todir=”${outputdir}”>
<fileset dir=”res”/>
</copy>

  • in the <src> tag, specify ${outputdir}/img instead of ${rootdir}/res as previously:

<src>
<fileset dir=”.”>
<include name=”src/**/*.*” />
<include name=”.locale_interfaces/**/*.java” />
<include name=”${outputdir}/img/**/*.*” />
</fileset>

Voila! I got the jar with the correct tree structure!

ALX

Creating the .alx file (which is used to install the application with the help of ApplicationLoader from BlackBerry Desktop Manager) was pretty straight forward with the <alx> task – here again I copied the necessary attributes from the BlackBerry_App_Descriptor.xml. The automation for that is on my task list, as already said.

Sign .cod file

The signing is done with <sigtool> task – it is pretty straightofrward. One thing I needed to fix is that when I installed signature keys they were put by Eclipse in C:eclipsepluginsnet.rim.ejdesignTool and not where the jdk was ( I suppose because I have multiple jdk’s installed)

So when I tried to specify jdehome=”C:eclipsepluginsnet.rim.ejde” I got  message ” ‘bin’ directory was not found”

On the other hand when I set the “jdehome” to C:eclipsepluginsnet.rim.ejde.componentpack4.6.0_4.6.0.23 where the actual jdk was installed, the singature keys wre not found. So I had to copy the keys from net.rim.ejdesignTool to net.rim.ejde.componentpack4.6.0_4.6.0.23componentsbin – and the .cod got signed.

OTA distribution

The final task was to generate the OTA (over the air) distribution package which is basically extracting the so called “sibling” .cod files from the big .cod file generated by rapc and putting the .jad file alongside them. Eclipse plugin creates this in ${porjectdir}/deliverables/Web directory.

I did it like this:

<target name=”OTA” depends=”sign” description=”Create OTA”>
<echo message=”Create OTA”/>
<unzip src=”${outputdir}att_connect.cod” dest=”${otadir}”/>
<copy file=”${outputdir}att_connect.jad” tofile=”${otadir}att_connect.jad”/>
</target>

Well, I think that’s all.

Hopefully someone finds this helpful. Comments are welcome.