XULRunner Application Development

NOTE this article was written for Monitor magazine, and appeared in the June 2006 issue.

Introduction

Once upon a time there was the Netscape Mosaic Browser, which morphed into the Communicator Suite, which morphed into the Mozilla project. For most of the journey, the focus was firmly on a suite of Web tools, namely a browser, email client, and an HTML editor. However, from the early days, 3rd party adopters started using the Mozilla code base for writing other applications and extensions. The community organisation, mozdev.org, recognised the potential of the Mozilla Platform and built a set of tools to accomodate Mozilla developers.

The development and subsequent success of the Firefox browser was a pivotal turning point. Not only did it symbolise Mozilla’s breaking free from the shackles of Netscape/AOL to become an independent organisation, but it brought into clear public view the full potential of the Mozilla code base. Modules and APIs were beginning to stabilise, new features were being added, and the UI toolkit was maturing. The Mozilla Foundation was paying attention too, and for the first time directly committed resources to working on the Platform in the form of the XULRunner project. This article will explain what XULRunner is, and give a step-by-step guide on setting up a XULRunner application. The example used is a upload program for the Marela photo sharing system.

What Is?

XULRunner is a platform, or environment, for running Mozilla applications, also known as the Gecko Runtime Environment (GRE). A distinction needs to be made at this point between the XULRunner base application, and your application. XULRunner will be referred to as the platform, while the code and features you write will be referred to as the application. The aims of XULRunner are to distribute a core set of stable modules, provide features for application development such as stable API modules, and enable features that are standard such as a customisable executable name, window icons, system profile handling, and more. For a listing of what modules will be shipped, and more details on the features, I recommend you browse through the related documents on the Mozilla Developer Center. XULRunner has already reached the point where it is being used in enterprise applications. Take for example, the AJAX Toolkit Framework, a plugin for the Eclipse IDE for developing web applications, or Songbird which is a full-featured media player.

Songbird
FIGURE 1: Songbird Media Player

If you are anxious to dive in and get an application up and running , there are 2 ways to get it. The first is to download a binary of XULRunner. The is a stable 1.8 Branch build, the 1.8.0.1 release, or a nightly trunk build. Though these trunk builds can be hit or miss in terms of stability, they contain the latest features. If you prefer more control or would like to contribute, the second method to get and use XULRunner is to download and build the source yourself. Instructions to do so are explained well in the Mozilla build documentation. If you use CVS to get the code, don’t forget to use the MOZ_CO_OPTIONS=xulrunner flag when checking it out. The examples in the rest of this article should be fine with all versions currently, and are aimed to get you up and running quickly with your first XULRunner application. This could be the porting of an existing extension to a Mozilla application, or a brand new program.

Application Structure

If you are familiar with Firefox or Thunderbird extension development, then the structure of a XULRunner application is very similar. Let’s have a look first at the directory structure of the Marela Uploader (package name – marup).

marup
|
|
———- application.ini
|
———- chrome.manifest
|
———- chrome
|
———- components
|
———- defaults
|
———- preferences

The application.ini file is the core of the application, which will not run without it. It contains configuration and version information. More on this in a later section. chrome.manifest is a text file for registering your application chrome (UI). Here are the entries for the marup package:

content  marup       jar:chrome/marup.jar!/content/
locale   marup       en-US   jar:chrome/marup.jar!/locale/en-US/
skin     marup       classic/1.0   jar:chrome/marup.jar!/skin/
Example 1: chrome.manifest for the Marela Uploader application

What this essentially does is map the registry to locations in the chrome JAR file, marup.jar which is located in the chrome/ folder in the package. Take the first line, which maps the URL chrome://marup/content/ to the content/ folder . Of course the folder structure can be what you like in the JAR, once it is correctly mapped here. Multiple locales and themes can be distributed once you register them using the correct language codes and theme names respectively. The components/ folder contains XPCOM components or JS components such as command line handlers. The defaults/ folder can be used as a dumping ground for any other files you need to distribute, but the preferences/ sub-folder should contain a file containing the default preferences for the application.

Setting up the Environment

Before distributing your application, you will need to pull some pieces together. The application.ini file contains the meta information needed for the application to run. The Marela Uploader file looks like this:

[App]
Vendor=Marela
Name=Uploader
Version=0.2
BuildID=20060119
Copyright=Copyright (c) 2006 Neko d.o.o.
[Gecko]
MinVersion=1.8
MaxVersion=1.9a1
Example 2: Sample application.ini

The important entries in Example 2 that you should keep in mind for now are Vendor and Name. The others should be self-explanatory. It is worth mentioning that at the time of writing the trunk version should use a MaxVersion of 1.9.a1 (an alpha release). If you want to enable the Extension Manager in your application, you’ll need to add another section [XRE] and add the entry EnableExtensionManager=true to it.

Next, the application has to know where to start, i.e. the entry point or what window will be launched first. This done via a preference. In the folder defaults/preferences/, create a JavaScript file (in marup it is called marup-prefs.js) and add the following entry:

pref("toolkit.defaultChromeURI", "chrome://marup/content/marup.xul");

The value will be different of course depending on the application. Then you have to decide if you want to allow multiple running instances of your application, or just a single one. If you just want one running instance, add this pref:

pref("toolkit.singletonWindowType", "marup:main");

The value set on this pref (marup:main) has to match the windowtype attribute in the XUL file that is being launched. At this point, as an application developer, you are all ready to package up your files and release them to the world.

Deployment

There are plans to distribute the platform with the ability to build installers for your application, but that is not yet completed. In the meantime, you have a few of choices for distribution. The first two involve user intervention and allow for distribution of the application independently in the XULRunner platform. The last is a more traditional approach, with the platform and the application bundled together. Note that the application as outlined earlier in the article can be distributed in a compressed archive (XPI/ZIP/JAR archive), or as flat files in a directory structure. The latter is useful for development, but it makes more sense to release it compressed because it requires a single download and less interaction from the user. The Marela Uploader is distributed as marup.xpi.

Register XULRunner

After you download XULRunner or build it from source, there are a Switching to the mode of being a user for a while, here is what you need to do to set things up. Firstly, register the GRE. From the command line, run this command:

xulrunner -register-global

This updates the registry on Windows (HKLM\Software\mozilla.org\GRE), and writes to /etc/gre.d on Linux for all system users. To register just for the current user, run:

xulrunner -register-user

One thing to watch out for is more than one system entry for the GRE. This can happen if you had a previous version of XULRunner installed. It is best to remove old versions, because there is the chance that the newer version could choke and not run otherwise.

Installing and Running the Marela Uploader

The firsts deployment method is launching from a flat directory structure on disk, and point XULRunner at the application.ini file:

xulrunner /path/to/marup/application.ini

This will launch the application directly from where it is unpacked on the system. When combined with having a flat chrome structure (and not a JAR file as shown in Example 1), this launch option is extremely useful for testing during the development phase of an application. No extra install step is necessary between writing the code and running the program.

Marela Uploader
FIGURE 2: Marela Uploader

Deployment method 2 is more common for production applications and requires the user to run the -install-app command. One thing to be aware of is that currently this is a primitive method in installation. Absolutely no feedback is given to the user.

Linux : ./xulrunner -install-app /path/to/marup.xpi
Installed to /usr/lib/<Vendor>/<Name>/

Mac : /Library/Frameworks/XUL.framework/xulrunner-bin -install-app /path/to/marup.xpi
Installed to /Applications/<Vendor>/<Name>/

Windows : xulrunner.exe -install-app c:\path\to\marup.xpi
Installed to c:\Program Files\Vendor\Name\
Example 3 : Using -install-app on different platforms

You are now all set to go and use the program, accessed via the locations shown in Example 3. Each application on the platform runs in it’s own process, thus ensuring peaceful co-existence with other Mozilla applications. You don’t have to worry about it taking down other applications if it crashes like Firefox extensions can do. Related to this, your application will have it’s own user profile space on disk. Once run for the first time, the profile is set up in the usual locations for Mozilla applications. For example, in ~/.// on Linux systems.

Bundled Distribution

Because of the less than elegant default options for bundling your application, some applications are already being distributed with custom installers. For example, the Songbird Preview available for Windows is shipped with a Nullsoft installer. The Zap! SIP Client includes XULRunner in it’s download package. These require a particular snapshot of the XULRunner code. and can not rely on the shifting sands of user-installed versions. Or in the case of Zap!, the tight integration with the Mozilla build system perhaps makes it easier to build XULRunner and package it up together with the application code. The ideal situation I’m sure for most vendors would be a customisable installer built-in to XULRunner, and an update mechanism for targeting specific releases of the platform. These are both in the works.

Future Directions

At the time of writing, a stable developer release (1.8.0.1) of XULRunner is available. In the roadmap, XULRunner 1.9 is slated to be the first production release of XULRunner, and is estimated to be shipped by Firefox 3 in the first quarter of 2007. So it doesn’t appear that Mozilla is in a hurry to release it. This is understandable because their primary focus is still on their product set including Firefox and Thunderbird. Much work remains to be done. The Embedding APIs for various platform specific options are not hooked in yet. These include PyXPCOM embedding, gtkmozembed on Linux, and activex control for Windows. Many bugs still need to be ironed out (289668, 319843, and 327392 for example), some if which will be trivial to fix and other a substantial amount of work.

Licensing is an issue that needs to be resolved. The Mozilla Public License is flexible enough to build commercial and closed source applications on top of the Mozilla code base, but Mozilla will need to protect themselves. So a balance needs to be found between a good EULA and one that does not interfere too much with the needs of the vendor. In an ideal world, all applications would be open but the reality is that intellectual property is still very much a part of the software deployment model. With XULRunner, there is not just an opportunity to provide a decent and stable platform, but also spread the Mozilla ethos and technologies further into the field of Web and Desktop application development.