Sunday, October 23, 2011

Starting a Lift project with SBT and IntelliJ

Getting up and running with Scala and Lift requires a lot of tools, especially if you want to develop from an IDE.  Coming from a Ruby on Rails and PHP background, a lot of this was new to me, and the books typically assume you've done a lot of Java development and are used to dealing with build tools, compiling, dependencies, etc.

So this is my guide for how to get started with Scala and Lift development, using the IntelliJ IDEA IDE, based on me spending hours and hours trying to figure it out.  I've used Rubymine and PHPStorm which are based on IntelliJ so IntelliJ is definitely my favorite IDE.  I believe you can also do Scala development from Eclipse and Netbeans.

I won't use the very latest version of everything, because the very latest of one thing might not be compatible with the other.  Also, this assumes you're using Linux, but it will be almost the same on Windows and Mac as most of the action happens in the sbt console.  I've gathered much of the info here from the Lift In Action book which I would highly recommend for learning Lift.  The setup part of this book wasn't completely comprehensive though and I spent a lot of time with trial and error to get to this point.

First step is getting Scala set up so you can run Scala from the command line.  This is actually optional, but you may occasionally want to manually run Scala code (like irb in Ruby), or compile a stand alone Scala script.  We're going to use version 2.8.1, since this is the latest that is compatible with everything else as of this writing.  (2.9.1 is the latest as of this writing)

  1. Download Scala 2.8.1.  
  2. Extract it to your /opt directory
  3. "ln -s /opt/scala-2.8.1-final /opt/scala" to create a symlink to your scala folder without having to use the version number.  
  4. "ln -s /opt/scala/bin/scala /usr/local/bin/scala" and "ln -s /opt/scala/bin/scalac /usr/local/bin/scalac" to make links to the scala executable and scala compiler so they'll be in your path.
Simple Build Tool (SBT) is the command line utility that you'll do pretty much all of the work from, other than editing files.  It will compile your code, run your code, load dependencies, load the correct version of Scala for your app, etc.  As of this writing, 0.11.0 is the latest.  However, after version 0.7.7, sbt had a lot of pretty fundamental changes that I don't like (what happened to it creating the project directory/file structure for you, specifying plugins through the sbt console instead of editing files, etc.)  I think version 0.7.7 is easier to use, and it's what the Lift In Action book is written for, so we'll install 0.7.7.
  1. Download sbt-launch-0.7.7.jar to /usr/local/bin.
  2. Create a file named sbt in /usr/local/bin with the contents:
    java -XX:+CMSClassUnloadingEnabled -XX:MaxPermSize=1024m -Xmx512M -Xss4M -jar `dirname $0`/sbt-launch-0.7.7.jar "$@"
  3. "chmod a+x /usr/local/bin/sbt" to allow it to execute
Create The Project
This is a little different that what you may be used to.  You'll actually create the project with sbt from the command line, not from your IDE.  
  1. Make a directory for your project and cd in to it
  2. Run "sbt".  It will ask you if you want to create a new project, enter y.
  3. Enter a name for your project
  4. Enter an organization.  
  5. Enter a version number for your app
  6. Enter 2.8.1 for the Scala version
  7. Use the default 0.7.7 for the sbt version
You don't need to download and install Lift, this is all done from a tool called Lifty which is a module to sbt.  It will give you a "lift" command in sbt that performs lift actions.  As of this writing, 1.6.1 is the latest released version of lifty, which only works with sbt 0.7.7.  There is a 1.7 beta that claims sbt 0.10 support.  We're going to go with 1.6.1.
  1. From an sbt prompt, enter "*lift is org.lifty lifty 1.6.1".  This will install the lifty module globally, to allow you to type lift.  (In newer versions of sbt, you can't do this, you have to edit a file and put Scala code in, why did they take out this ability?)
  2. Assuming you're in the project directory, run "lift create project-blank".  This will make your project a Lift project, with the default files. 
  3. Leave the default value for mainpack
  4. Enter 2.3 for the liftversion (this is important, do not use the default 2.3-RC version, or 2.4 which is not compatible with Scala 2.8.1)
  5. Enter "reload" at the prompt to reload the project definition
  6. Enter "update" to compile your blank app
Your app is now compiled and ready to run!  You can type jetty-run to start up a web server for your app, then navigate to localhost:8080.  Type enter then jetty-stop to stop the server.

IntelliJ IDEA Project
I didn't forget about using IntelliJ IDEA.  Before you open the directory in IntelliJ, you need to create an IntelliJ project file so IntelliJ knows where everything is.  This is done from the sbt-idea processor.
  1. From an sbt prompt, type "*sbtIdeaRepo at"  sbt-idea is not in the standard repo so you'll need to add a reference to it with this command.
  2. Install it with "*idea is com.github.mpeltonen sbt-idea-processor 0.4.0".  This will add "idea" as an option to the sbt prompt.  
  3. Type "update" to update references
  4. In your project directory, type "idea".  This will create the project file for IntelliJ.
IntelliJ IDEA
Now on to the IntelliJ program itself.  
  1. Load IntelliJ IDEA, and before opening the project, go to File, Settings, Plugins. 
  2. In the Available tab, add the Scala and SBT plugins.
  3. Restart IntelliJ, go to File, Open Project, and find your project.  It will take some time to index everything.
  4. You'll see an error "Cannot load facet Web".  Click Details and click Yes to remove it."
  5. You MAY have to add the lib and lib_managed folders as libraries.  I can't explain it, I had to do this on the first project I set up, on the second I didn't.  If you do, go to File, Project Structure, Libraries, Add a New Project Library called Libs, Attach Jar Directories, and pick the lib and lib_managed/scala-2.8.1/compile folders.  Also for some reason, it will not pick up some of the Lift JAR files that are in lib_managed.  I could not get it to recognize mapper, so on this same page I had to click Add Classes and pick the mapper JAR file in lib_managed.  
  6. You'll have to configure the SBT plugin.  Go to File, Settings, SBT.  Under IDE settings, enter /usr/local/bin/sbt-launch-0.7.7.jar for SBT launcher JAR file
Now that this is configured, you can use the SBT console at the bottom.  Just click start, and you'll get a prompt for this project.  This is where you'll want to run everything from.

If you want to use break points and everything else that comes along with debugging, from IntelliJ:
  1. From the drop down on the top menu, click Edit Configurations
  2. Click +, then Remote.
  3. Give it a name (like jetty debug)
  4. In the Before Launch section, check Run SBT Action
  5. Click the ... beside Run SBT Action
  6. Check Run in current module
  7. Enter jetty-run for the action
  8. Click File, Settings, SBT.  
  9. Add the following to the end of the VM Parameters line under IDE settings: "-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005"
You're all set.  Just click the Debug button, and you're good to go.  SBT will be launched with jetty-run, and you can now debug (note that if you already had an SBT console open, you'll have to kill it).

So, that's all there is to it!  :)  This is a lot to go through to get going, but now that you've got all of this set up, you should have everything you need to develop with Scala and Lift, and distribute the code when you're done.

1 comment:

Yossarian said...


very very useful post. complete scala lift newbiew, this really helped. few errors though:

1. org.lifty not org.Lifty and lifty not Lifty. this is very important because this apparently matches the maven groupId artifactId and version unique identifier convention, and so you actually describe a different artifact which doesn't exist...

2. i had to start off with defining scala 2.7.7 on everything, get lifty 1.6.1 and only then change scala to 2.8.1 and reload/update. the reason is that there is no lifty 1.6.1 built for scala 2.8.1 available on the default repositories. there is however a lifty 1.6.1 built for scala 2.7.7

i hope other people find this post useful.