Scala Servlet HowTo

Burak Emir


Table of Contents

Introduction
What is this about ?
Why another style/language of writing servlets ?
How to read this tutorial
Getting Started
Example servlets
Directory structure
Building and Deploying
Tips
Scala
Tomcat

Introduction

What is this about ?

Servlets are a nice and easy way to write web applications.

Scala is a general-purpose language with facilities for semistructured data processing.

Together they make a good couple.

Why another style/language of writing servlets ?

Servlet programming has roughly evolved like this

  • Model 1 - string glueing .  Servlets write HTML output directly into streams, leading to code like:

                    out.println("<html>...</html>");
                  
    This is tedious, because errors in markup are only discovered at runtime. Model 1 is a Bad Idea(tm) since it forces the programmer to mix "logic" and "presentation". It was just the first attempt at serving HTML anyway.

  • Model 2 - MVC .  The Model-View-Controller design pattern, applied to servlet programming, boils down to this: The view part is handled by JSPs, mixture of HTML and Java code. The servlets contain only "logic". The controller is realized in a framework; the programmer supplies the model (Java beans, data-only classes) and the program logic in servlets, now called "actions". In JSP (Java server pages) one writes debatable things like

                <html>
                  <% MyData md = request.getAttribute("myData"); %>
                  <h1><%=md.getHeading()%></h1>
                  <% for ( int i = 0; i < md.lines(); i++ ) { %>
                  <p><%=md.getLine( i )%></p>
                  <% } %>
                </html>
              
    These will the get compiled to a servlet that deals with nothing but presentation. Note that we can

    • neither check whether code within <% %> is correct if JSPs get compiled lazily. You need a precompiler, and its error messages suck

      (JSP gurus can extends JSPs with tag libraries, which somehow means falling back on Model 1 described above,)

    • nor check whether the markup produced conforms to a DTD or a Schema.

In Scala we can combine literal XML with expressions in a general-purpose programming language. The well-formedness of the resulting XML is checked (XML spec lawyers hurry to talk about id tags that need to be unique in a wellformed document, but nobody listens to them anyway). You can write "Hello World" like this

  def doGetXML( req:HttpServletRequest ) = 
    <html>
      <head>
        <title>Hello World</title>
      </head>
      <body>
        <h1>Hello World</h1>
        <p>
          The time is <b>{ Text( java.util.Calendar.getInstance().getTime().toString() ) }</b>
        </p>
      </body>
    </html>

Enforcing a typing discipline (automatic validation against a DTD, an XML Schema, or a Relax NG spec) is an ongoing research topic at LAMP. Recently, Lukas Rytz completed a nice project to this end.

How to read this tutorial

You will need to know these things:

  • $(classpath) - the value of the classpath environment variable

  • $(scala) - the directory in which Scala is installed

  • $(scalaservlet) - the directory of the example source

  • $(tomcat) - the directory in which tomcat is installed.

For Scala gurus:

  • When you update scala, make sure that you also update the file scala.jar, which comes with the distribution.

For Tomcat gurus: You may of course deploy servlets any way you like.

Getting Started

  1. Install Java, Scala, Ant and Tomcat

  2. Compile and run the example servlets (see below)

  3. Write your own servlets

Example servlets

Directory structure

For convenience, the examples are built using ant. This tool allows to easily compile all scala sources that are within a directory hierarchy.

The files are organized like this:

  • build.xml - directs the ant tool to build the servlets

  • descr - contains web.xml, the "deployment descriptor"

  • lib

    • scala.jar the scala library

    • servlet.jar the javax.servlet library. This file contains only interfaces and is only needed during compilation.

  • src the sources

    • ScalaHttpServlet.scala - an adapter for scala servlets, that takes care of XML serialization.

    • HelloWorld.scala - a scala servlet that produces a friendly greeting.

    • ParameterPassing.scala - a scala servlet that shows one way to pass arguments to servlets

    • ModularFormatting.scala - a scala servlet that shows how one can modularize HTML formatting.

Building and Deploying

Building

Building describes the process compiling source files to class files.

The Scala servlet examples can all built using the standard scalac compiler (as can be seen in the build file).It is no longer necessary to give the -Xmarkup option.

  1. go to the directory $(scalaservlet)

  2. edit ant.properties to set tomcat.home to your $(tomcat) and scala.home to your $(scala).

  3. make sure your $(classpath) contains scala.jar,tools.jar and fjbg.jar.

  4. run ant. You should get the message BUILD SUCCESSFUL and a new directory build

Deploying

Once the servlet classes are built, they have to be deployed. Deploying means moving class files to some place where a servlet engine (in our case Tomcat) can find them.

  1. copy the build directory to the webapps directory, using (Unix)

                rm -Rf $(tomcat)/webapps/scalaExample
                cp -r build $(tomcat)/webapps/scalaExample
              

  2. start Tomcat. If Tomcat is already up, you can either shut it down and start it up again, or reload the scalaExample "context" (see Tips below).

  3. Visit localhost:8080/ScalaServlet/index.html

Tips

Scala

Avoid writing classes that do not live in a package.

You can instantiate any Java class, you can use all of the Java API.

The Scala API provides a facility for parsing XML. The schema2src tool allows you to create specific Scala classes and traits for XML element types specified in a DTD (and maybe, one day, WXS).

Writing literal XML expression works in every Scala program. Eclipse syntax highlighting prefers if the outermost tags are enclosed in parenthesis, like so: val foo = (<html>...</html>)

In older version of Scala, a class foo used to get compiled to a class foo$class and an interface foo and one had to write foo$$class to reference such a class in a config file - those days are over for classes, only traits are still compiled that way).

Tomcat

Have a look at the "manager" service. If you have configured some user waith the role "manager" in $(tomcat)/conf/tomcat-users.xml, then you can access the url:

          http://localhost:8080/manager/reload?path=/ScalaServlet
        

If deploying is still to cumbersome, and you are comfortable with defining tasks in ant, try figuring out org.apache.catalina.ant.DeployTask in $(tomcat)/server/lib/catalina.jar

If you do not use your own logging facility, then debug messages printed with Console.println will end up in the log file catalina.out. The same holds for stack traces of exception.

If you have several Scala web applications, you can place scala-library.jar in $(tomcat)/shared/lib instead of putting it in each WEB-INF/lib.