Deploying OpenLaszlo Applications with Rake

Compiling and debugging an OpenLaszlo application is just part of the picture. Often there are assets that need to be compiled into an application, and things that need to be done with the application binary once it is complete.

At some point, once you reach a certain level of application or site complexity, you need a build script to automate the build and deployment steps. For side projects, I've been using Rake.

Here's how to use Rake to build an OpenLaszlo application. Once you do this, you'll be able to type rake hello.swf to compile an OpenLaszlo source file. More to the point, Rake can also create whatever other XML and image files your application depends on (provided you tell Rake how to build them), and you'll be able to type commands such as rake deploy to both compile the application and copy to a server -- provided, again, you've told Rake how to do this. There are examples of all of this below.

h2. Installation

First, install Ruby, and Rake. The easiest way to install Rake is to install rubygems and then type gem install rake. If you're on a Mac you'll need to type sudo gem install rake instead. (And if you're on a Mac, you probably already have Ruby. It comes pre-installed.) Update: You should install rubygems. It's now the endorsed way to install the ruby OpenLaszlo module, below.

Second, download openlaszlo.rb, and copy it into a directory on your Ruby library path. (You can examine your library path by executing ruby -e 'puts $:'.) You may need an admin password to do this.[1]

Second, install the ROpenLaszlo gem:
[code]
gem install -r ropenlaszlo
[/code]

Finally, you need to set some shell environment variables. OPENLASZLO_HOME is the location of the OpenLaszlo SDK on the file system. If you're using the binary install, set it to /Applications/OpenLaszlo Server 3.1. OPENLASZLO_URL is the URL of the OpenLaszlo server; for example, http://localhost:8080/lps-3.1. You can set these from the shell, or place this in your .bashrc_profile or the equivalent:
[code]
export OPENLASZLO_HOME=/Applications/OpenLaszlo Server 3.1
export OPENLASZLO_URL=http://localhost:8080/lps-3.1
[/code]

That does it for system setup. Here's what you do for each project:

h2. Usage

A project needs to live in a directory inside your OpenLaszlo server directory. For example, if you're using the OpenLaszlo 3.1 binary install on a Mac, you might use to /Applications/OpenLaszlo Server 3.1/Server/lps-3.1/my-apps. I build from a source tree that is synced to ~/laszlo/lps-dev, so I keep my projects in subdirectories of that.

Go ahead and make a new subdirectory inside the server directory, say hello. Put two files in this directory. The first is an OpenLaszlo source file, hello.lzx:
[code]
Hello Rake
[/code]

The second is Rakefile:
[code]
require 'openlaszlo'
[/code]

[code]
require 'openlaszlo'
[/code]

[code]

rule '.swf' => '.lzx' do |t|
puts "Compiling #{t.source} => #{t.name}" if verbose
OpenLaszlo::compile t.source, :output => t.name
end
[/code]

Type rake hello.swf into the shell, and you'll get a file hello.swf in the same directory:
[code]
> rake hello.swf
(in /Users/oliversteele/laszlo/lps-dev/hello)
Compiling hello.lzx => hello.swf
> ls -l hello.swf
-rw-r--r-- 1 oliverst www 73035 Jan 5 12:49 hello.swf
[/code]

Execute rake hello.swf, and nothing will happen:
[code]
> rake hello.swf
[/code]
...until you change the source file or delete hello.swf:
[code]
> touch hello.lzx
> rake hello.swf
(in /Users/oliversteele/laszlo/lps-dev/hello)
Compiling hello.lzx => hello.swf
[/code]

h2. Why Bother?

That was a lot of trouble just to do the same thing you could already do with lzc. Why bother?

One reason is that it's faster. I told you to set the OPENLASZLO_URL environment variable. That tells the OpenLaszlo module (and therefore the Rake task which uses it) to use the OpenLaszlo server to compile applications, and this can be a lot faster than using lzc[2]. For example, on my 1.5MHz PowerBook, rake hello.swf takes 18s, as compared to 35s for lzc hello.lzx.[3]

Of course, you could get the same speed by using the browser to run your application, and you're doing this anyway when you debug it, so what's are the real advantages?

As with any task automation, they're repeatability, and single-stop shopping. Let's take the second first.

h3. Complex Builds

First, Rake goes beyond browser-based compile and lzc, in that it can be used to build files that the swf file depends on. For example, my home page button bar depends on an XML file for configuration, and some static text images to work around the problem that the Flash player can't apply opacity to client fonts. (And since I've only got a little bit of text in my application, I don't want to bother embedding a font.)

I use a rakefile similar to the one above for this application, but with the following additional lines:
[code]
file 'nav.swf' => ['projects.xml', 'label.png']

file 'label.png' do |t|
sh "convert -background transparent label:'(enter search text here)' #{t.name}"
end

file 'projects.xml' => ['index.rb', 'projects.yaml'] do |t|
require 'projects.rb'
make_xml t.name
end
[/code]

The first line supplements the *.lzx -> *.swf rule above, with the information that this particular file additionally depends on the files projects.xml and label.png. The next two forms tell Rake how to use ImageMagick, and a function defined in another file, to make these.

Now I can execute rake nav.swf to rebuild whichever of label.png, projects.xml, and nav.swf is required.

A word of warning: Unlike the browser-based compiler, Rake doesn't know any more about your source file dependencies than what you tell it. For example, if nav.lzx includes mylib.lzx and functions.js, Rake won't know to recompile nav.swf if either of these files changes (but nav.lzx doesn't). You'll need to add:
[code]
file 'nav.swf' => ['mylib.lzx', 'functions.js']
[/code]
to your rakefile to tell it about them.

h4. Deployment

The other reason to include your OpenLaszlo application builds in a build system is that that way you can automate deployment too. My deployment set consists of HTML files, PHP files, OpenLaszlo swfs, and auxiliary images, some created by hand, and some produced by other tools. I build them all locally, so that I can test them in a staging directory, but at some point I upload them to a web site -- and that's when I notice the typo, and need to do it all again. Adding a deploy task makes this easy:
[code]
FILES = %w{index.php header.php footer.php nav.swf}
STAGING_URL = 'ows@osteele.com/staging.osteele.com'
DEPLOYMENT_URL = 'ows@osteele.com/osteele.com'

task :staging => FILES do
sh "rsync -avz -e ssh #{UPLOADS.join(' ')} #{STAGING_URL}"
end

task :deploy => FILES do
sh "rsync -avz -e ssh #{UPLOADS.join(' ')} #{DEPLOYMENT_URL}"
end
[/code]

And now rake deploy builds everything locally, and then copies everything that's changed to a deployment server.

And I can get back to actually writing code.

Updated 2006-01-11: The OpenLaszlo module is now available as a gem.


fn1. Alternatively, you can add a directory where you have write permission to your search path (add export RUBYLIB=~/lib/ruby to your .bash_profile or equivalent), and copy openlaszlo.rb there.

The OpenLaszlo ruby library is only a day old. After it's baked for a while I'll turn it into a gem, and then these installation instructions will be simpler.

fn2. First, because it doesn't have to start a JVM process for each compile, and second, because the JVM process doesn't have to load the script cache when it starts up. (Loading the script cache is slow, but compiling without it is even slower.)

fn3. All of these times are for a recompile -- after the file has been compiled once, and then trivially changed. The initial compile is slower -- sometimes a lot slower -- but isn't as representative of the edit-compile-debug cycle.

8 Responses to “Deploying OpenLaszlo Applications with Rake”

  1. togawa manabu Says:

    very cool!!
    I’d like to try this but looks a openlaszlo.rb file is 404 not found on here.
    where can I get this file?

  2. Oliver Says:

    Oops! The link works now. Hope you enjoyed my 404 :-)

  3. OpenLaszlo Project Blog » ROpenLaszlo is available as a Ruby Gem Says:

    [...] The “OpenLaszlo” module that was announced “a few days ago”:http://weblog.openlaszlo.org/archives/2006/01/deploying-openlaszlo-applications-with-rake/ is now available as a Ruby gem. This means that installing it on your system is as simple as typing “ruby gem install ropenlaszlo” — assuming you’ve already got Ruby and Rubygems. [...]

  4. Mushtaq Says:

    What should be the OPENLASZLO_HOME if I have installed “Development Kit for Any OS” (the .war file without tomcat)?

  5. Languages of the real and artificial · OpenLaszlo Ruby library Says:

    [...] openlaszlo.rb is a Ruby library for compiling OpenLaszlo programs. I use it to build this, this, and the toolbar here. This article describes how to use it with Rake. [...]

  6. Jason Says:

    I’ve just started trying to automate my laszlo projects build using ruby. The trouble I am having is that when OPENLASZLO_URL is set nothing happens! It works fine with just OPENLASZLO_HOME set but not otherwise.

    Platform:
    OSX 10.4.5

  7. Rich Says:

    In the rakefile, the require lines don’t work for me. This works:

    require ‘rubygems’
    require ‘ropenlaszlo’

  8. Rich Says:

    Many people seem to be having the same problem that I have. First of all, set OPENLASZLO_HOME as follows:

    export OPENLASZLO_HOME=/Applications/OpenLaszlo\ Server\ 4.0.2 # location of the OpenLaszlo SDK on the file system

    The problem seems to be in OPENLASZLO_URL. CONTRARY TO THE DOCS, you need to set it as follows:

    export OPENLASZLO_HOME=/Applications/OpenLaszlo\ Server\ 4.0.2/Server/lps-4.0.2 # location of the OpenLaszlo SDK on the file system

    Notice the addition of ‘/Server/lps-4.0.2′. This will prevent the 404 errors that you might be getting on compliation.

    P.S. I tried to use the command-line based compiler, but it died every time I tried to use the ‘runtime’ parameter…Weird.