Rapid Lift application development with Eclipse and JRebel

In this article I’ll describe the setup I use to do develop Lift applications. While more heavy-weight than if an interpreted language is used, I find this setup provides fairly decent turnaround times.

So, it took a little longer than expected to write this article which continues where the previous stopped. But all good things come to he who waits :-) The software used in the previous article all had major updates in the meantime:

Scala 2.8 (2.8.1 is just around the corner)

Eclipse 3.6

Scale IDE for Eclipse (though a nightly build is currently needed for Eclipse 3.6)

Eclipse

I’m using the latest Eclipse 3.6 (Helios), which can be found here. Install it and launch with a new workspace.

JRebel

JRebel allows you to make code changes and have the changes reflected in your running app without restarting. This is very handy for a rapid development cycle. It’s not perfect and doesn’t work with all changes, but most of the time it picks up the changes ok. Note that you can get a free license if you only work with Scala files!

Follow step 1-3 in the instructions here to download and install JRebel as well as the JRebel Eclipse plugin.

Select the Scala perspective (click on ‘+’ the first time and select “Other..”)

Right-click in Package Explorer and select New->Scala Project

Enter helloworld as Project name

Expand the project, right-click on the src folder and select New->Scala Application

Enter “HelloWorld” as Object name

Add println(“Hello, World”)

Right-click in the editor and select Run As->Scala Application

Note, that since this is a nightly build, there may be times when the plugin is not in a good shape. Seek help on the scala-ide mailing list :-)

Creating the Lift Eclipse project

Since we’re using Gradle to manage the dependencies to external JARs (see previous article for details), we need to tell Eclipse where in the file system those jars can be found. You need to find this directory on your system. It’s usally in ~/.gradle/cache which for me maps to /Users/Jeppe/.gradle/cache.

So we create a classpath variable, GRADLE_CACHE that points to this directory. Open Eclipse preferences:

The created Lift application contains a main object that runs an embedded Jetty container which is very useful for development. It’s located in src/test/scala/RunWepApp.scala. Right-click this file and select Run As->Scala Application. Now Jetty starts up and you can navigate to http://localhost:8080 to see the application.

The final step is to enable JRebel for the Run configuration just created. Select “Run Configurations” and find RunWebApp$, select the JRebel tab and enable the JRebel agent.

Restart the application. JRebel should print something to the console.

JRebel in action

Now try to change something. Go to src/main/scala/example/snippet/HelloWorld.scala.

Change the output of the howdy snippet by e.g. replacing “d.toString()” with some text.

Save the file in order to compile it.

Refresh the page in the browser.

Watch the new content be displayed in the browser!

Watch the console output that says JRebel has reloaded the class

As mentioned earlier, not everything can be reloaded by JRebel and not everything in Lift can be changed during runtime.

If JRebel cannot reload the changes, you usually get a runtime error (ClassNotFound, ClassCastException etc) and you’ll have to restart. If JRebel does pickup your changes and nothing happens, chances are that Lift cannot dynamically pick up the changes. Examples of the latter are:

Things that happen in Boot. Your application is not re-booted to pickup the changes. This unfortunately includes SiteMap changes.

Addition/removal of mapper fields. The fields of a mapped object are determined at startup and cannot change at runtime.

So, this completes the post. Enjoy! And please provide feedback if you have any ideas to improve the development cycle!

Like you posts about the lift framework, since its realy not easy to start with. Also appritiate the use of graddle.

Could you provide an example how to use Lift with JPA? Perhaps as a mixed Java/Scla project.
As a start, maybe you could just post as reply, how to do JPA Bytecode Enhancement on Entity classes in graddle after java/scala compile task.

I like your post and have started to try it. After the liftstart got running, then importing into Eclipse I get some 27 errors.
starting with RunWebApp saying mortbay in not a value of package org, another error in AppTest is that junit is not a member of package root.
It sounds like something basic is wrong. Can you direct me to a place that might be able to help me address the issue?

Outstanding! Your liftstart on github is updated to 2.8.1 and 2.4-M1, I tried it with 2.9.0 and 2.4-M3 but there is a problem with the javamail (pom is looking for 1.4.4). however, it works perfectly with scala 2.9.0 and lift 2.4-M2.

quick question if you have a sec as I am not familiar with Gradle (yet :-)), once this is setup how do you handle adding additional dependencies in build.gradle, i.e. say I need amqp added in, what is needed to get library downloaded once I add dependency to build.gradle? do I need to do anything to get eclipse to recognize new libraries?

To add a dependency, change the dependencies {} section. You probably need to add to the “compile” section in the same way as the lift dependencies. You should run “./gradlew eclipseClasspath” to generate a new Eclipse .classpath file with the new dependencies.