Read on and leave a comment
or return to our portfolio.

2 Mar 2011

by Dave

Setting the run.mode in Lift web apps

Update: You can now set the run mode easy and conveniently using our sbt-runmode plugin for SBT.

Setting the run.mode in Lift applications is the source of a surprising number of questions. The documentation recommends passing it as a parameter when the JVM is invoked. This can be hard to achieve for various reasons. In our case our deployment is automated using Chef, and scripts to start and stop the Jetty web server are installed by the package manager. We don’t really want to monkey around with these scripts, so we had to find another way. Jetty is written in Java, which means it must have a ridiculously complex XML configuration language. The Jetty developers turned it up to 11 by making their configuration language Turing complete, so we can actually set the system properties in a configuration file. The file we want to create isWEB-INF/jetty-web.xml and we want it to contain this:

 

<?xml version=”1.0″?>
<!DOCTYPE Configure PUBLIC “-//Mort Bay Consulting//DTD Configure//EN” “http://jetty.mortbay.org/configure.dtd”>
<Configure class=”org.mortbay.jetty.webapp.WebAppContext”>
  <Call class=”java.lang.System” name=”setProperty”>
    <Arg>run.mode</Arg>
    <Arg>production</Arg>
  </Call>
</Configure>

 

If we leave this around then our application will always run in production mode. We don’t want this when we’re developing as we won’t, for instance, get stack traces printed to the browser. Thus we should copy this file in when we package up the project, and remove it when the packaging step completes. Assuming you’re using SBT, store the above text in project/jetty-web.xml and add the following to your SBT project file to get this functionality:

 

  val jettyWebPath = “src” / “main” / “webapp” / “WEB-INF” / “jetty-web.xml”
  lazy val installProductionRunMode = task {
    FileUtilities.copyFile(“project” / “jetty-web.xml”,
                           jettyWebPath,
                           log)
    log.info(“Copied jetty-web.xml into place”)
    None
  } describedAs(“Install a jetty-web.xml that sets the run mode to production”)
  lazy val superPackage = super.packageAction dependsOn(installProductionRunMode)
  lazy val removeProductionRunMode = task {
    FileUtilities.clean(jettyWebPath, log)
    None
  } describedAs(“Remove jetty-web.xml and hence set run mode back to testing”)
  override def packageAction = removeProductionRunMode dependsOn(superPackage) describedAs BasicWebScalaProject.PackageWarDescription

 

This is pretty simple code. Basically it redefines the package action to first copy in the jetty-web.xml file, then it runs the original package action, and finally it deletes the jetty-web.xml. Now any WARfiles you run under Jetty will automatically be in production mode, but callingsbt jetty-run will still give you development mode.

Posted in Code, Scala, Web development | No Comments »

Comments are closed.