Mittwoch, 11. August 2010

Lift + Scala, Installation + First contact

I have installed Lift and Scala on a Linux computer running the current Ubuntu version 10.04. Depending on your distribution, the commands may be different.

What you need is:
  • maven2 - a Java software project management and comprehension tool
  • jetty - a Java servlet engine
  • Java
Note that this is not the only possible configuration. There are other project management tools like SBT and other servlet engines, e.g. Tomcat. However, the documentation I've seen mostly describes maven and jetty.

Installation of Scala

Please note: The following step will install Scala. It also lets you run Scala commands interactively from the command line. This is a very good learning tool, especially for beginners.

This is a modified version of the instructions given by the London Scala User Group Dojo:

  • Warning: Do not use Scala from the Ubuntu (10.04) repositories. The repo contains an older 2.7 variant - we want 2.8!
  • Create a folder that will hold one or more versions of Scala:
    sudo mkdir /opt/scala
  • Change that folders ownership to your username:
    sudo chown -R username.username /opt/scala
  • From http://www.scala-lang.org/downloads download Scala final for Unix, Mac OS X, Cygwin. This is a gziped tar archive file.
  • Open the dowloaded file (Archive manager - file-roller) and extract to /opt/scala/
  • Create a sybolic link (future proof the install):
    ln -s /opt/scala/scala-2.8.0.final /opt/scala/current
  • Define environment variable SCALA_HOME by editing ~/.bashrc and adding the line:
    export SCALA_HOME=/opt/scala/current
  • Add the Scala executables to your path by editing ~/.bashrc and adding the line:
    export PATH=$PATH:$SCALA_HOME/bin
  • Open a new terminal or load the changes in your ~/.bashrc file using the command:
    source ~/.bashrc
  • Test scala is working using the following command:
    scala -version or scalac -version
    You should see the following as output:
    Scala code runner version 2.8.0.final -- Copyright 2002-2010, LAMP/EPFL
    Scala compiler version 2.8.0.final -- Copyright 2002-2010, LAMP/EPFL

The version of Scala used for compiling the web app is stored in the maven repos and is at the moment (Juli 2010) at version 2.8.0.RC7. It will be downloaded and executed during the build process.

Installation of Java

Ubuntu comes with OpenJDK as standard. You might want to download the official Java from Sun... I mean Oracle:
  • Enable the partner repositories in Synaptic (or uncomment them in /etc/apt/sources.list) and reload the indices:
    sudo apt-get update
  • Download Java
    sudo apt-get install sun-java6-jdk sun-java6-plugin
  • Switch to the Oracle version:
    sudo update-alternatives --config java
    sudo update-alternatives --config javac

Installation of maven2 and jetty

sudo apt-get install maven2 jetty


Your first lift application:

Go into an empty directory an issue the following maven2 command:

mvn archetype:generate \
-DarchetypeGroupId=net.liftweb \
-DarchetypeArtifactId=lift-archetype-blank \
-DarchetypeVersion=2.0-scala280-SNAPSHOT \
-DarchetypeRepository=http://scala-tools.org/repo-snapshots \
-DremoteRepositories=http://scala-tools.org/repo-snapshots \
-DgroupId=com.example  \
-DartifactId=lift.test \
-Dversion=0.1 \
-DscalaVersion=2.8.0.RC7 

An archetype is a project template. lift-archetype-blank is a simple example Lift application, which is downloaded from http://scala-tools.org/repo-snapshots. You can browse this repository at http://scala-tools.org/repo-snapshots/net/liftweb
If you use http://scala-tools.org/repo-releases instead you get older more stable builds. repo-snapshots contains the nightly builds.
  • The artifactId (lift.test) is the name of the top level directory for this project (your choice).
  • The groupId is mapped (Java style: com.example becomes com/example) to the ./src/main/scala directory (also your choice).
  • version refers to the version of YOUR software.
  • scalaVersion of Scala in the maven repo.
After the download the project tree looks like this


This might look scary at first. But there are only 10 files.
./pom.xml
./src/main/scala/bootstrap/liftweb/Boot.scala
./src/main/scala/com/example/snippet/HelloWorld.scala
./src/main/webapp/index.html
./src/main/webapp/templates-hidden/default.html

./src/main/webapp/WEB-INF/web.xml
./src/packageLinkDefs.properties
./src/test/scala/com/example/AppTest.scala
./src/test/scala/LiftConsole.scala
./src/test/scala/RunWebApp.scala 

I'm not sure yet about the last group. My guess is they are used for unit testing and packaging of the WAR files for later deployment.

As for the first group:
  • pom.xml:
    This is the maven configuration file.
    It contains (among others) the URL of the repositories and the dependencies which have to be resolved during the build process. You will rarely edit this file. However, if you need modules that are not within the “standard” scope (e.g. a connector to MySQL servers), you have to edit this file in order to get them drawn into your project.
  • Boot.scala (in ./src/main/scala/bootstrap/liftweb/):
    This file contains code that is run once when the application is started.
    It is used to set-up menus, database connections, etc. You will have to edit this Scala code frequently when you want to use and configure these features.
  • index.html (in ./src/main/webapp/):
    The default template
    This is the template that is evaluated when you access it via the application server without any special file name (e.g. http://localhost:8080/). You will most likely create other templates.
    This particular template refers back to
  • default.html (in ./src/main/webapp/templates-hidden/default.html).
    This is also a template, but one that you will rarely change. It defines the “frame” in which your application runs, i.e. header, footer, menu bar, the html HEAD section (page title, meta tags, CSS definitions, etc.).
    Not all of its content is static. This file may contain Lift tags, most commonly the ones for displaying the menu, to change the page title, and to display feedback to the user (error messages, notices, warnings).
    You may create and use more of these “frame” templates, but in most cases you only need one.
  • HelloWorld.scala (in ./src/main/scala/com/example/snippet/):
    a so called snippet.
    These files contain the Scala code which fills the in the templates (e.g. index.html). This is where most of your coding will happen. You will create more than one snippet file.
Some folders are currently empty:
model, view, comet (in ./src/main/scala/com/example/).

In the example code I have seen so far, Scala code that defines persistent data structures (e.g. for a database) is stored here.

Bringing your application to life

In order to start the application change into the top directory (lift.web) and type
mvn jetty:run

After maven has finished downloading all dependencies and building the application, you can access the web application in your browser via http://localhost:8080

Montag, 9. August 2010

Lift + Scala, Introduction

A recent show of Floss Weekly made me curious about Lift, a web framework using Scala.  

“Scala is a general purpose programming language designed to express common programming patterns in a concise, elegant, and type-safe way.” so they promise  on the Scala website.

The Lift project leader praises his product as “a concise language, frame work with security features, very performant...”

A first glance

Lift, like any framework that you haven't written yourself, will take some time getting familiar with, and Scala, well, it's just another computer language... or so I thought.

Lift

Perhaps the most important feature of Lift is its template system.  These templates are strictly XML based text files without any programming logic.  Tags within the template link to functions in your Scala code that generates some output.  This output (also XML) then replaces the tag.  After a few more processing steps the result is returned to the enquiring web browser, your page gets rendered, end of story.  Yes, there are lots of support features within the framework – like html form generation, database connectivity, page access control – but this is the basic principle of Lift.

Scala

The designers of Scala cherry-picked the best features and concepts from other programming languages, some object-oriented stuff but they also borrowed heavily from functional programming. Its mantra: “everything is an object” and “if it's worth saying, say it with a function”.

Scala's smart compiler can in most cases infer types of variables, so you don't have to declare it manually.  The language has lots of these simplyfications, dramatical reducing boiler plate code.  However, you have to be familiar with these in order to be able to revert the expression back to its more verbose form, otherwise you will scratch your head when you encounter the “Scala smiley”:

 ( _ + _ )

Some language constructs help you avoiding Null pointer dereferences, or to catch all possible cases in a matching construct.  And being a statically typed language  the Scala compiler will be very stubborn if your types don't match.

You can write very elegant code – even though I wouldn't call deeply nested function calls simple to read, at least not yet.

Treacherous simplicity

Letting the compiler infer types looks like a good idea.  On second sight, it also means that you need a good memory or at least a helpful IDE.

Simplifying
   val a: Int = 1

to
   val a = 1

is simple and easy to understand. (The literal 1 is an integer, i.e. “a” must be integer as well). But:

val a = function_i_wrote_ealier_and_dont_remember_the_return_type()
val b = another_cool_function_from_the_web_framework(User => go look)

does work just as well. And now you either know the types or you have to look it up.

The possibility to drop dots and brackets in some situation lets you further “simplify” things:
   a.+(b)

becomes a much more friendlier
   a + b
(+ is a valid function name in Scala).

But
   a :: b

does not mean
   a.::(b)

but
   b.::(a)


(“Operators” that end with “:” bind from right to left).

Another nice feature: When defining a class how often have you assigned the values from the constructor parameter list to class variables for later use? It's usually the first thing you do.  In Scala this is done automatically.  Why hasn't somebody invented this earlier? 

Documentation + support

There is documentation available for Lift and Scala on the web.  While perhaps not exactly light reading, they will get you started.

For Scala http://programming-scala.labs.oreilly.com/index.html from O'Reilly is a good start, and on the Scala website there is http://www.scala-lang.org/docu/files/ScalaByExample.pdf.  Both publications expect that you have done some programming before.

For Lift you should check out master.pdf from http://groups.google.com/group/the-lift-book/files. More information is available at the Lift Wiki and a subscription to the Lift newsgroup is also recommended.