The Play! Framework offers a new way to develop web applications. Relying on a stateless model, a light but complete stack and no big turnaround times for debugging, Play! makes developing Scala applications really efficient. akquinet is using Play! in several projects. But, what makes Play! even better and your development even more efficient is the Scala support. You can develop your application using the Scala language.
This blog post explains how to set up Play! and your development environment to develop web applications efficiently. It covers the Play framework and the Scala module installation, the integration inside the Eclipse IDE, the Source Code Management configuration and the deployment into Apache Tomcat and JBoss AS.
First, you have to download the Play framework from http://www.playframework.org/download. Unzip the archive to a folder. We’ll call that folder PLAY_HOME from now on.
$ wget [http://download.playframework.org/releases/play-1.2.2.zip] $ unzip play-1.2.2.zip $ cd play-1.2.1 $ export PLAY_HOME=`pwd`
Play itself is already nice, but we add a little extra and use Play together with Scala. So we have to install the Scala module to activate the Scala support for Play.
$ cd $PLAY_HOME $ ./play install scala
Now I can create my first application with
$ ./play new helloworld --with scala
Yes, that’s all. Enter the start command
$ ./play run helloworld
and in your favorite internet browser you can open http://localhost:9000/ and see your application running.
Now you can edit the code and start developing, but I like to have some support during the development. Of course you can install the Scala syntax highlighting for vim from http://lorenzod8n.wordpress.com/2008/01/11/getting-scala-syntax-hightlighting-to-work-in-vim/, but sometimes you like to have a little more integrated environment. That means IDE support, a Source Code Control System, deployment, continuous integration and all that stuff. This post covers IDE integration and source code control. The continuous integration will be covered later in another post.
First: it’s nice to have IDE support. We use Eclipse, therefore we install the Scala plugin for Eclipse from http://www.scala-ide.org/ and run:
$ cd helloworld/ $ ../play eclipsify
Fine, now I can import my project into Eclipse as an existing project. The current version (Play version 1.2.2 and Scala module 0.9.1) generates code from the HTML files and uses it in the controllers like
The code is stored in a local tmp directory, therefore we had to add the directory tmp/classes as a class folder to the project build path. From here we just code our project, save it and immediately see the results in the browser – no big turn around…
The next step is to have a Source Code Management system. At the moment we use subversion and git (depending on the project). In this post we use git, but using any other SCM technology is pretty straightforward. Normally I would simply add the project to a git repository. Still in the project folder
$ git init $ git add * $ git commit -a -m “initial checkin”
Fine, from here you can work as usual. But the first time you share your project with another developer, you’ll encounter a problem. If a Play project uses a dependency, Play creates a module directory and puts a file for every dependency in that directory. The content of the module directory is
m4500 6 (helloworld) >ls -al modules/ insgesamt 12 drwxr-xr-x 2 rmagnus rmagnus 4096 2011-06-22 23:39 . drwxr-xr-x 11 rmagnus rmagnus 4096 2011-06-28 09:52 .. -rw-r--r-- 1 rmagnus rmagnus 55 2011-06-22 23:39 scala-0.9.1 m4500 7 (helloworld) >cat modules/scala-0.9.1 /home/rmagnus/projects/play-1.2.2RC1/modules/scala-0.9.1
There is an absolute path stored here which does not work for other workspaces. So we changed the content of modules/scala-0.9 from
The next step would be the deployment. Play itself offers a really good http server, but most production systems already have an application server and you don’t want two servers on one system for the same reason. So I have to deploy the application into an existing application server. In this post we cover Apache Tomcat and JBoss Application Server.
The first thing we need is a deployable war file. Play provides a way to build a complete war file embedding all dependencies:
$ cd $PLAY_HOME $ mkdir deploy $ ./play war helloworld -o deploy/helloworld
The original example on the Play website says ‘-o helloworld.war’ – but don’t get confused. The result isn’t a file, it’s a directory.
Now we copy the directory to the Apache Tomcat webapps folder
cp -avu deploy/helloworld ~/env_dev/apache-tomcat-5.5.26/webapps/
and check the Tomcat output
03.07.2011 22:12:45 org.apache.catalina.loader.WebappClassLoader validateJarFile INFO: validateJarFile(/home/rmagnus/env_dev/apache-tomcat-5.5.26/webapps/helloworld/WEB-INF/lib/geronimo-servlet_2.5_spec-1.2.jar) - jar not loaded. See Servlet Spec 2.3, section 9.7.2. Offending class: javax/servlet/Servlet.class 22:12:45,155 INFO ~ Starting /home/rmagnus/env_dev/apache-tomcat-5.5.26/webapps/helloworld/WEB-INF/application 22:12:45,156 INFO ~ Module scala is available (/home/rmagnus/env_dev/apache-tomcat-5.5.26/webapps/helloworld/WEB-INF/application/modules/scala-0.9.1) 22:12:45,808 INFO ~ Application is precompiled 22:12:46,012 INFO ~ Application 'helloworld' is now started !
that’s it for Apache Tomcat. If you want to configure your artifact, create a ‘war/WEB-INF’ directory in your application. Here you can put additional configuration files. We’ll need this for the JBoss AS example.
The current Play version (1.2.2 with Scala modul 0.8.1) produces a NullPointerException in the ScalaTemplate class in JBoss – so I have to run this example with Play version 1.2.1.
We’re using JBoss AS 6.0. But here we have to add an additional file to prevent JBoss from scanning the application annotation (see https://issues.jboss.org/browse/ISPN-1046).
$ mkdir -p helloworld/war/WEB-INF $ vim helloworld/war/WEB-INF/jboss-scanning.xml
The content of jboss-scanning.xml is simple
<scanning xmlns="urn:jboss:scanning:1.0"> <!-- Purpose: Disable scanning for annotations in contained deployment. --> </scanning>
Let’s create the artifact again and copy it to the JBoss.
$ cd $PLAY_HOME $ mkdir deploy $ ./play war helloworld -o deploy/helloworld.war $ cp -avu deploy/helloworld.war/ ~/env_dev/jboss-6.0.0.Final/server/default/deploy/
The extension ‘.war’ is very important here! Otherwise JBoss will not recognize the application as an exploded war archive and will not process the jboss-scanning.xml file and we’ll get a lot of errors. So using ‘<application>.war’ as the naming pattern for your output directory seems to be good practice.
After copying it, JBoss AS is writing some good news:
18:09:31,975 INFO [org.jboss.web.tomcat.service.deployers.TomcatDeployment] deploy, ctxPath=/helloworld 18:09:32,130 INFO [STDOUT] 18:09:32,129 INFO ~ Starting /home/rmagnus/env_dev/jboss-6.0.0.Final/server/default/deploy/helloworld.war/WEB-INF/application 18:09:32,131 INFO [STDOUT] 18:09:32,131 INFO ~ Module scala is available (/home/rmagnus/env_dev/jboss-6.0.0.Final/server/default/deploy/helloworld.war/WEB-INF/application/modules/scala-0.9) 18:09:33,184 INFO [STDOUT] 18:09:33,183 INFO ~ Application is precompiled 18:09:33,231 INFO [net.sf.oval.Validator] gnu.trove collection classes are available. 18:09:33,322 ERROR [STDERR] SLF4J: Class path contains multiple SLF4J bindings. 18:09:33,322 ERROR [STDERR] SLF4J: Found binding in [vfs:/home/rmagnus/env_dev/jboss-6.0.0.Final/common/lib/slf4j-jboss-logmanager.jar/org/slf4j/impl/StaticLoggerBinder.class] 18:09:33,322 ERROR [STDERR] SLF4J: Found binding in [vfs:/home/rmagnus/env_dev/jboss-6.0.0.Final/server/default/deploy/helloworld.war/WEB-INF/lib/slf4j-log4j12-1.6.1.jar/org/slf4j/impl/StaticLoggerBinder.class] 18:09:33,323 ERROR [STDERR] SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation. 18:09:33,412 INFO [STDOUT] 18:09:33,412 INFO ~ Application 'helloworld' is now started !
Again – that’s it, very nice.
There is one thing that is a little bit annoying: The lib directory for the application is 47MB and contains a lot of libraries which you don’t really need in a JBoss environment, like org.eclipse.jdt.core-3.6.0.jar and scalatest-1.2-for-scala-2.8.0.RC7-SNAPSHOT.jar. We hope there’ll be a way around this in the future.
This post has presented how you can start efficiently developing web applications using the Play! framework and Scala. It has covered the installation and configuration of Play!, the IDE and SCM management and the deployment into a production server (Apache Tomcat and JBOSS AS 6.0). Thanks to these tips, you’re now able to develop a nice web application and go live pretty fast. Another blog post will present how this ‘live’ deployment can be automated using a continuous integration server such as Jenkins.