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 ApplicationLift uses Maven Archetype plugin to build a template project.
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=my.liftapp -DartifactId=liftapp
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.
cd liftapp
mvn install
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 v3I could simply deploy the application on GlassFish v3 server by doing:
asadmin deploy target/liftapp-1.0-SNAPSHOT
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.
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:
<pluginRepositories>
<pluginRepository>
<id>maven2.java.net</id>
<name>Java.net Repository for Maven 2</name>
<url>http://download.java.net/maven/2</url>
</pluginRepository>
</pluginRepositories>
<plugins>
<plugin>
<groupId>org.glassfish</groupId>
<artifactId>maven-glassfish-plugin</artifactId>
<version>1.0-alpha-4</version>
<configuration>
<resourcesDirectory>target/liftapp-${project.version}</resourcesDirectory>
</configuration>
</plugin>
</plugins>
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
def howdy = Welcome to liftapp at {new java.util.Date}
by
def howdy = Welcome to liftapp deployed on GlassFish v3 at {new java.util.Date}
Save this file and run mvn install and hit Entner key in the windows where I ran embedded GlassFish v3.
That'sNow, 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
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
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
- 4700 reads





