Techno Barje

Headless Xulrunner

Here is a summary on how to run a xulrunner application on an headless computer, or more commonly just launch xulrunner in a command line with no windows.


By default, xulrunner try to open a XUL window defined in the ""toolkit.defaultChromeURI"" preference, so you have to set this one to an empty value.


Then you need to have a running X server, even if it never open any window … one simple and lightweight solution is running Xvfb. But any other X server will do the work!


Finally, I suggest you to take the 1.9.0.14 xulrunner release which has less painfull dependencies like libalsa (due to ogg support) and libdbus-glib.


This will avoid this kind of errors :

./xulrunner-bin: error while loading shared libraries: libasound.so.2: cannot open shared object file: No such file or directory
./xulrunner-bin: error while loading shared libraries: libdbus-glib-1.so.2: cannot open shared object file: No such file or directory

How to write such a tutorial without a complete working out of the box hello world ?
Here is a sample command line application with linux xulrunner binaries : headless-runner.tar.gz

$ tar zxvf headless-runner.tar.gz
$ cd headless-runner
$ Xvfb :2
$ export DISPLAY=:2
$ ./headless -ls -filesize application.ini
LS :
 - application.ini
 - a.out
 - tests
 - components
 - defaults
 - updates
 - extensions
 - xulrunner-1.9.2a2pre.en-US.linux-x86_64.tar.bz2
 - xulrunner
 - headless

$ ./headless -filesize application.ini
File size of : application.ini
  243

The main code is in the file components/nsCommandLineHandler.js

CommandLineHandler.prototype.handle = function(aCmdLine){
  
  var toggle = aCmdLine.handleFlag("ls", false);
  if (toggle) {
    dump("LS : 
");
    var list = aCmdLine.workingDirectory.directoryEntries;
    while(list.hasMoreElements()) {
      var file = list.getNext().QueryInterface(Components.interfaces.nsIFile);
      dump(" - "+file.leafName+"
");
    }
    dump("
");
  }

  var filesize = aCmdLine.handleFlagWithParam("filesize", false);
  if (filesize) {
    dump("File size of : "+filesize+"
");
    var file = aCmdLine.resolveFile(filesize);
    if (!file)
      return dump("Unable to find this file
");
    dump("  "+file.fileSize+"
");
  }
}

For more information, check the nsICommandLine interface of the aCmdLine object.


Last but not least, why do I try to use Xulrunner in command line whereas xpcshell and "js" commands exists?!

  • First: Some tools like Mccoy are bundled as xulrunner application. And you may launch these tools on headless servers in order to build, for example, continuous integration tools!
  • Second: JS shell allow you tu use only pure Javascript; Xpcshell expose all XPCOM but some part of Mozilla environnement are disabled! I was unabled to create a <canvas> element in xpcshell. There is no way to create a XUL/HTML document/element with XPCOM and hiddenWindow is disabled … So the only solution to build a tool which takes website screenshots with <canvas> was using xulrunner!