Scala Lift Web Framework on GlassFish v3
During JavaOne I heard about Lift - a Scala web framework and wanted to try it.
It claims to provide best of Rails(simple and fast development), Seaside(security), Django(access control by default)
and uses Wicket for view templates. In few steps I had my first Lift
web application running on GlassFish v3.
Lift applicatin development process is Maven based and uses Derby as the default database. These are the steps to build a simple Lift application and
deploy it on Embedded GlassFish v3 during development or deploy it on GlassFish v3 server.
Create Application
Lift uses Maven Archetype plugin to build a template project.
[prettify] mvn org.apache.maven.plugins:maven-archetype-plugin:1.0-alpha-7:create \ -DarchetypeGroupId=net.liftweb \ -DarchetypeArtifactId=lift-archetype-basic \ -DarchetypeVersion=0.8 \ -DremoteRepositories=http://scala-tools.org/repo-releases \ -DgroupId=<b>my.liftapp</b> <b>-DartifactId=liftapp</b>
[/prettify]
This created liftapp directory.
- src/main/scala directory contains the Scala source code.
- src/main/webapp directory contains the HTML, JavaScript, CSS, and WEB-INF code.
- lift_example directory contains the derby database.
Now let's build it
[prettify] cd liftapp mvn install
[/prettify]
This would create a WAR directory structure at target/liftapp-1.0-SNAPSHOT/ and also the WAR file
target/liftapp-1.0-SNAPSHOT.war
Deploy on GlassFish v3
I could simply deploy the application on GlassFish v3 server by doing:
[prettify] asadmin deploy target/liftapp-1.0-SNAPSHOT
[/prettify]
Click http://localhost:8080/liftapp-1.0-SNAPSHOT/ and you
should see the Welcome screen. Also note that the access controls login, add user features are automatically generated similar to
Django admin.
Code-Save-Refresh with GlassFish v3
The previous deployment on to GlassFish v3 works fine but I needed something that could help me do Code-Save-Refresh cycle without
restarting the v3 server. Basically I wanted to use Embedded GlassFish v3 where I would simply invoke mvn glassfish:run and
make changes and compile in another window and at the end refresh the browser to see the changes.
Since pom.xml generated by
Lift Archetype does not have entry for maven-glassfish-plugin so I had to add this plugin entry:
[prettify] &lt;pluginRepositories> &lt;pluginRepository> &lt;id>maven2.java.net&lt;/id> &lt;name>Java.net Repository for Maven 2&lt;/name> &lt;url>http://download.java.net/maven/2&lt;/url> &lt;/pluginRepository> &lt;/pluginRepositories> &lt;plugins> &lt;plugin> &lt;groupId>org.glassfish&lt;/groupId> &lt;artifactId>maven-glassfish-plugin&lt;/artifactId> &lt;version>1.0-alpha-4&lt;/version> &lt;configuration> &lt;resourcesDirectory>target/liftapp-${project.version}&lt;/resourcesDirectory> &lt;/configuration> &lt;/plugin> &lt;/plugins>
[/prettify]
I also had to make one more change in src/main/webapp/WEB-INF/web.xml to workaround due to the fact that
http://java.sun.com/j2ee/dtds/web-app_2_3.dtd has been renamed to http://java.sun.com/dtd/web-app_2_3.dtd and
the aliasing is not happening properly with Embedded GlassFish v3
So the change was to edit src/main/webapp/WEB-INF/web.xml and replace http://java.sun.com/j2ee/dtds/web-app_2_3.dtd
by http://java.sun.com/dtd/web-app_2_3.dtd. This step would not be required once it is fixed in embedded GlassFish v3.
That's it! Next I did was invoke mvn glassfish:run
vivekmz@boson(620)> mvn glassfish:run
[INFO] Scanning for projects...
[INFO] Searching repository for plugin with prefix: 'glassfish'.
[INFO] ------------------------------------------------------------------------
[INFO] Building liftapp
[INFO] task-segment: [glassfish:run]
[INFO] ------------------------------------------------------------------------
[INFO] Preparing glassfish:run
[INFO] [resources:resources]
[INFO] Using default encoding to copy filtered resources.
[INFO] [yuicompressor:compress {execution: default}]
[INFO] nb warnings: 0, nb errors: 0
Downloading: http://scala-tools.org/repo-releases/org/igniterealtime/smack/smack/3.0.... Downloading: http://repo1.maven.org/maven2/org/igniterealtime/smack/smack/3.0.4/smack... Downloading: http://scala-tools.org/repo-releases/org/igniterealtime/smack/smackx/3.0... Downloading: http://repo1.maven.org/maven2/org/igniterealtime/smack/smackx/3.0.4/smac... [INFO] [compiler:compile]
[INFO] Nothing to compile - all classes are up to date
[INFO] [scala:compile {execution: default}]
[INFO] Nothing to compile - all classes are up to date
[INFO] [glassfish:run]
May 16, 2008 2:52:31 PM com.sun.enterprise.v3.server.AppServerStartup run
INFO: HK2 initialized in 236 ms
May 16, 2008 2:52:31 PM com.sun.enterprise.v3.server.AppServerStartup run
INFO: com.sun.enterprise.naming.impl.ServicesHookup@1e708b2 Init done in 241 ms
May 16, 2008 2:52:31 PM com.sun.enterprise.v3.server.AppServerStartup run
INFO: com.sun.enterprise.v3.server.Globals@1fbc355 Init done in 242 ms
May 16, 2008 2:52:31 PM com.sun.enterprise.v3.server.AppServerStartup run
INFO: com.sun.enterprise.v3.server.SystemTasks@1f2edd2 Init done in 246 ms
May 16, 2008 2:52:31 PM com.sun.enterprise.v3.server.AppServerStartup run
INFO: com.sun.enterprise.v3.services.impl.HouseKeeper@f221f6 Init done in 247 ms
May 16, 2008 2:52:31 PM com.sun.enterprise.v3.server.AppServerStartup run
INFO: com.sun.enterprise.v3.services.impl.CmdLineParamProcessor@189a773 Init done in 249 ms
JMXMP connector server URL = service:jmx:jmxmp://localhost:8888
May 16, 2008 2:52:31 PM com.sun.enterprise.v3.services.impl.GrizzlyProxy start
INFO: Listening on port 8080
May 16, 2008 2:52:31 PM com.sun.enterprise.v3.server.AppServerStartup run
INFO: com.sun.enterprise.v3.services.impl.GrizzlyService@154ea79 startup done in 398 ms
May 16, 2008 2:52:31 PM com.sun.enterprise.v3.services.impl.ApplicationLoaderService postConstruct
INFO: loader service postConstruct started at 1210978351811
May 16, 2008 2:52:31 PM com.sun.enterprise.v3.server.AppServerStartup run
INFO: Application Loader startup done in 431 ms
May 16, 2008 2:52:31 PM com.sun.enterprise.v3.server.AppServerStartup run
INFO: Glassfish v3 started in 432 ms
May 16, 2008 2:52:37 PM com.sun.enterprise.web.WebModuleContextConfig authenticatorConfig
SEVERE: webModuleContextConfig.missingRealm
Hit ENTER for redeploy
Click http://localhost:8080/liftapp/ would display

Then I tried to make some changes in the Scala code compile it and then refresh the browser to see if the changes appear there.
So in another window, edit src/main/scala/my/liftapp/snippet/HelloWorld.scala
Replace
[prettify] def howdy = <span>Welcome to liftapp at {new java.util.Date}</span>
[/prettify]
by
[prettify] def howdy = <span>Welcome to liftapp <b>deployed on GlassFish v3</b> at {new java.util.Date}</span>
[/prettify]
Save this file and run mvn install and hit Entner key in the windows where I ran embedded GlassFish v3.
That's
Now, I go back to the browser and refresh the window and it displays the changed text, but first see the GlassFish log
where you hit Enter and see the log printed when refresh button was pressed in the browser
[prettify] Hit ENTER for redeploy May 16, 2008 2:57:30 PM com.sun.enterprise.web.WebModuleContextConfig authenticatorConfig SEVERE: webModuleContextConfig.missingRealm INFO - Service request (GET) /liftapp/ took 412 Milliseconds INFO - Service request (GET) /liftapp/classpath/blueprint/screen.css took 13 Milliseconds INFO - Service request (GET) /liftapp/classpath/blueprint/print.css took 2 Milliseconds INFO - Service request (GET) /liftapp/classpath/blueprint/plugins/fancy-type/fancy-type.css took 2 Milliseconds INFO - Service request (GET) /liftapp/classpath/jquery.js took 4 Milliseconds INFO - Service request (GET) /liftapp/classpath/json.js took 1 Milliseconds
[/prettify]

To summarize, a Scala Lift application can be deployed on GlassFish v3 server as well as can be run in development
mode with hot deployment by running embedded GlassFish mvn glassfish:run. Go ahead and try it out and let us know at
the the forum or alias
- Login or register to post comments
- Printer-friendly version
- vivekp's blog
- 5154 reads





