My favorites | Sign in
Project Logo
                
Search
for
Updated Nov 21, 2009 by dmharrah
WebApplications  

Web Applications

This page describes some features of sbt that are useful for developing web applications.

Basic Usage

Instead of extending sbt.DefaultProject in your project definition, extend sbt.DefaultWebProject. This currently does two things. First, the package action creates a war file instead of a jar file. Second, if you add Jetty as a dependency (manually or automatically), you can use jetty-run to start your web application from sbt. Use jetty-stop to stop it. If you are running in batch mode, use the jetty action, which will wait for a key press before completing.

Configuration

sbt uses the directory structure of Maven by default, so your web application files should go in src/main/webapp by default. You can override webappPath to change this. If you need to include extra files in your web application, override extraWebappFiles with a PathFinder that selects the extra files that you want (see Paths for information on PathFinder). To change the port Jetty starts up on, override jettyPort.

Continuous Redeployment

You can also continuously recompile and reload the web application when using Jetty:

> jetty-run
> ~ prepare-webapp

jetty-run starts Jetty and the ~ prepare-webapp recompiles and recreates the web application whenever sources files change (see TriggeredExecution for details on ~). The jetty-run action monitors the directories given by scanDirectories and redeploys on changes. By default, the entire temporary web application directory is monitored. You might want to change scanDirectories in some cases. For example, set scanDirectories to Nil if you do not want to redeploy on any changes. Or, set scanDirectories to only monitor the library and classes directories:

  override def scanDirectories = ( temporaryWarPath / "WEB-INF" / ("classes" | "lib") ).get.toSeq

You might use one of these options if your web application picks up changes to resource files and therefore does not need to be redeployed or if you are using JRebel.

Another possibility is to directly run the web application out of the the source web application path:

  override def jettyWebappPath  = webappPath
  override def scanDirectories = mainCompilePath :: testCompilePath :: Nil

Example

A minimal project definition might be:

class WebappBuild(info: ProjectInfo) extends DefaultWebProject(info)
{
  val jetty6 = "org.mortbay.jetty" % "jetty" % "6.1.14" % "test"  // jetty is only need for testing
}

For a runnable example, see the WebApplicationExample page, which describes running the Hello Lift example with sbt.

JRebel

To use JRebel, override scanDirectories as described above so that sbt does not reload Jetty on changes to your classes:

  override def scanDirectories = Nil

Pass the following options to java in your sbt startup script:

-noverify -javaagent:/path/to/jrebel/jrebel.jar

Comment by jeremy.mawson.work, Apr 25, 2009

I needed to include jasper too, before jetty would start.

val jasper = "org.apache.tomcat" % "jasper" % "6.0.18"

Comment by dmharrah, Apr 25, 2009

This is a minimal project definition for Jetty support. Other dependencies are needed if your project project requires them. HelloLiftExample? works for me without needing this dependency, for example. If this doesn't address your comment, please feel free to follow up here or on the mailing list.

Thanks, Mark

Comment by davetron5000, Aug 08, 2009

Continuous Redeployment doesn't seem to work on classes. Changes to web.xml, e.g. do take effect.

Scala users can get a free license for JavaRebel? via http://www.zeroturnaround.com/scala-license/ and that allegedly will reload your changed classes.

Comment by dmharrah, Aug 08, 2009

You might have run into  issue #35 . This is fixed in the 0.5.3-p1 snapshot1?. If it is still broken for you, please report it as a bug.

Thanks, Mark

1? Note that you can update the version of sbt used by your project by typing the following at the sbt prompt:

set sbt.version 0.5.3-p1
Comment by davetron5000, Aug 09, 2009

Not only will it allegedly reload your classes, it does. Awesome. Highly recommend JavaRebel?

Comment by antony.stubbs, Aug 10, 2009

I think a note needs to be added about what you "name" your jetty dependency - because calling it "jetty" clashes with the jetty definition in super.

Comment by aleksand...@gmail.com, Nov 21, 2009

Rename "JavaRebel?" -> "JRebel" as it changed its name.

Comment by aleksand...@gmail.com, Nov 21, 2009

I have ended up with such configuration for JRebel (while running cc action):

  override def jettyWebappPath = webappPath 
  override def scanDirectories = Nil

instead of:

  override def jettyWebappPath = webappPath 
  override def scanDirectories = mainCompilePath :: testCompilePath :: Nil

Please, inline my config instead of this reference: "override scanDirectories as described above", because with (mainCompilePath :: testCompilePath) on scan path Jetty will be reloaded, what is not desired with JRebel.

And maybe note about cc in JRebel section too.


Sign in to add a comment
Hosted by Google Code