« HotSpot Arithmetic | Main | Work Distribution in RabbitMQ »

Scalarizing Velocity

It is quite well documented that Scala is a boon to those who need to extend or integrate Java based applications and libraries. Recently, I found myself implementing some some new back end functionality for a website that uses Velocity to render its frontend. Whilst doing this, a few gotchas arose:

  • Scala collections do not work out of the box with a Velocity foreach loop;
  • Velocity expects the attributes of an object instance to be exposed via the JavaBean getter/setter convention;

However, a small amount of googling some simple solutions for these problems.

Automatically Convert Scala Collections To Java

Whilst the reverse operation is well documented, there does not appear to be an inbuilt mechanism to convert Scala collections to Java. The solution to this has been provided by Jorge Ortiz's scala-javautils library on Github.

This uses an implicit conversion that allows you to invoke a function called asJava on any Scala collection to get it converted to a Java collection. Just refer to the README on the Github project page to see how easy this is. After applying this to my Scala collections, the Velocity templates are now able to iterate through them.

Expose Attributes As JavaBean accessors

One of the nice things about Scala is the paradigm shift away from unnecessary JavaBean accessors. However, Velocity, unless I'm unaware of of some magical configuration parameter, follows the JavaBean mantra, which can be a hassle when you just want your template to read the properties of a class instance.

Thankfully there is an on-board feature that can auto-generate getters and setters for your attributes. By annotating a field with the @BeanProperty annotation, the Scala compiler will automatically generate these methods for you, thus saving you from unnecessary boilerplate in your Scala code. An example looks like this:

package foo

import reflect.BeanProperty

class Bar {
  @BeanProperty var id:Long = -1
}

This allows you to use plain jane JavaBean accessors in your Velocity templates.

If Scala Can Drive Velocity

A third option may be of interest to you, if you are invoking the template application from within Scala code. Martin Kneissl wrote this Scala wrapper for Velocity, which addresses the Java collection issue in Scala.

YMMV.

Posted on Sunday, June 7, 2009 at 10:28PM by Registered Commenter0x6e6562 in | Comments1 Comment

Reader Comments (1)

hi,

at least in 2.8 - and i think in 2.7 too - conversions do seem to go both ways. all you need to do is import the implicit classes (not sure i have the right term - i am new to scala).

in 2.8:
import scala.collection.JavaConversions._

in 2.7:
import scala.collection.jcl.Convertions._ (or something similar - haven't used this).

that's enough for things to just work.

discalimer - i am a complete scala newbie, came here via a google search looking for info on attributes.

my "author url" links to a blog post i just wrote about this, but the basic idea is as above.

andrew

October 10, 2009 | Unregistered Commenterandrew cooke

PostPost a New Comment

Enter your information below to add a new comment.

My response is on my own website »
Author Email (optional):
Author URL (optional):
Post:
 
Some HTML allowed: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <code> <em> <i> <strike> <strong>