Deploying a Scala Lift Application in an OSGi Container

My current project involves building a Lift web application and deploying it in our OSGi application container.  I've been working with Scala on and off for a while, and I've always been interested in Lift.  With the release of Scala 2.8 and Lift 2.0, I decided it was time to give Lift a real try on my current project. 

The easiest way to deploy a WAR file is using Pax Web's War Extender. This allows you to simply deploy a WAR file with an updated MANFIEST.MF file (making it an OSGi Bundle) in the same container as Pax Web. In my example I will build a WAR file as a standard OSGi Plugin and build it using Eclipse, but you could also build a normal WAR file using Maven or SBT and add the OSGi attributes to the MANIFEST.MF file and deploy it with Pax Web.

The following steps assume:
  • Eclipse is the IDE
  • Scala-IDE (Scala Plugin) is installed.
  • Scala 2.8
  • Lift 2.0 (Need the Scala 2.8 Snapshot from Scala-Tools)
The first step was to create a standard OSGi Plug-In Project.  Then edit the project file to add the Scala Build Command
<buildcommand> 
  <name>ch.epfl.lamp.sdt.core.scalabuilder</name>
</buildcommand>
to buildSpec, and remove the Java Builder

Then add the Scala Nature
<nature>ch.epfl.lamp.sdt.core.scalanature</nature>
to natures. I added both to the top of the respective sections.

You will then need to reload the Project (Close/Reopen) and it should be Scala-enabled.

I then merged the Lift Template project into my Eclipse Project.  I copied the src/main/scala directory into my src directory, and src/main/webapp into the project root.

At this point Eclipse should see the Scala source files, but they will not compile as the Lift libraries are not yet in the classpath.

I downloaded the required dependencies from the various Maven repositories and added them to the WEB-INF/lib directory.  For my initial project I needed:
  • joda-time
  • lift-actor
  • lift-common
  • lift-json
  • lift-util
  • lift-webkit
  • paranamer-generator
  • slf4j
  • org.apache.commons.fileupload
Remember, if you are using Scala 2.8 to download the 2.8.0 version of the lift libraries (which are currently under snapshots instead of releases).  Once you have all the dependencies, the Lift sample code should compile.

You can now work on deploying the bundle.

You will need the Pax Web WAR Extender bundle and all its dependencies.  They can be found in this Maven Repo, and are outlined here for version 0.7.1.

Once the Pax Web bundles are deployed, you should be able to deploy your bundle.  The Pax Web WAR Extender will scan all bundles for a web.xml file and attempt to deploy them if it finds one.

By default it uses the Bundle's Symbolic Name (Bundle-SymbolicName: xxx) as the context root, but you can specify your own by adding the following line to your MANIFEST.MF:
Webapp-Context: /
to deploy as the root context or
Webapp-Context: mycontext
to deploy as /mycontext

That was all it took to get a sample Lift application up and running. I can now use the OSGi container to reference other dependencies and continue to build the application in Eclipse.

A couple of notes:
You can deploy the Lift libraries and dependencies as OSGi bundles instead of in the WEB-INF/lib directory of the bundle. At the time of this writing, the Lift OSGi Bundles were not available for 2.8 yet, but all they need are an updated MANIFEST.MF file.

As I noted at the beginning, you can simply edit the MANIFEST.MF file of any WAR and deploy it this way. If your Lift app does not depend on other OSGi bundles this may be the easiest approach.