Get hands-on training for JIRA Software, Confluence, and more at Atlassian Summit Europe. Register now ›

Why Scala?

Scala is currently gaining a lot of traction in the Java community, for a number of reasons. Twitter replaced it’s Ruby-based messaging backbone with one written in Scala. It also has a lot going for it as a language, and also compiles to bytecode just as Java does (Martin Odersky wrote both the Scala compiler and the current javac reference compiler).

What does this language have over Java?

There’s a lot, and some of it certainly looks fairly strange compared to Java. Examples of some of the extras:

Methods as first-class objects:


//won't actually compile due to type constraints, but illustrates the point..
def run(method, param) = { method(param) }
run(System.out.println, "text")

Closures (of course! And lambda expressions here…):

var total = 0
List(1,2,3).foreach { x => total += x }

Static Typing:

No groovy-style fail-at-runtime typing. Everything here is statically typed and checked at compile time. Difference is that things are inferred, otherwise you need to declare the type:

var thing = 1
var other : Any = 1
thing = "new" //fail, was inferred as an integer
other = "new" //ok, marked as anything (value or ref type)

Traits:

Think interfaces with some code. And yes you can inherit multiple of them. So you effectively get mixins, or sort-of simple multiple inheritance.

There are a lot more; some more simple ones which I’ve missed from C# are Properties and more sensible super-constructor calling (class myClass(i : Int) extends mySuper(i){...}), but I won’t go into the rest here. The language supports both OO and functional styles, so at the cost of complexity keeps both camps happy. There is plenty of scope for many Scala posts, and I’ll probably do a Friday presentation on it soon, so I’ll keep this post primarily concerned with how to write plugins in Scala. If you want more information on the language itself, check out the main Scala site.

How do you create a plugin with this?

Build

To build Scala code you can use a Maven2 plugin, and put code in src/main/scala & src/test/scala:

org.scala-tools
maven-scala-plugin

scala-compile-first
process-resources

add-source
compile

scala-test-compile
process-test-resources

testCompile

Or you can use your IDE. Idea 9 has a Scala plugin which is fairly good, it supports syntax highlighting, a few basic refactorings and some debugging. I believe Eclipse also has some Scala support.

Deploy

To run a Scala plugin in a standard Java app you simply need to add the runtime jar org.scala-lang:scala-library. Other than that you should be fine, and the code should just work. The main issues you are likely to have are with containers…

Problems

Velocity & WebWork

Yes, you don’t really have to use Velocity, but when writing a Confluence plugin it’s pretty tempting. Velocity will work with Scala, but you need to be aware of some things. Here is an example action:

class ScalaAction extends ConfluenceActionSupport {
@scala.reflect.BeanProperty
var myNumber : int = 21
@scala.reflect.BeanProperty
var myString : String = "testString"
def execute = {
try {
myString = //do something
} catch {
case e: Exception => myString = "error!"
}
Action.SUCCESS
}
}

The main thing to notice here is the @scala.reflect.BeanProperty annotations. This means that Scala will generate standard getters and setters for these properties, which can then be used by Velocity and WebWork as if you were using Java. Without using this annotation (and if you do), Scala will generate a getter/setter pair as propertyName() / propertyName_eq$(...) instead of getPropertyName() / setPropertyName(...). (Note that you can also annotate the whole class with @scala.reflect.BeanInfo to create getters/setters on every property.) I suppose you could still call the Scala getter with $action.myProperty(), but you’d lose WebWork injecting the properties.

Spring

Spring has identical issues to those above – i.e. using setter injection (mandatory for Confluence plugins-1 plugins) need getters and setters. There are however a few options other than using the above annotations. You could use a FactoryBean - although this also causes issues in plugins-1, top level beans are simply created and used, if you want some Spring magic, then it’ll need to be a nested bean definition. I hoped that Spring would easily let me redefine the methods which it used to get and set bean properties, however it uses the standard Java Introspector to find these methods. Apparently this is being rewritten in Spring 3.0 (I haven’t yet tried it) to allow using custom methods, so general Scala support could be added fairly simply with this. Note however that many Scala zealots are not a fan of using a DI framework as Scala is flexible enough to do this itself (like Groovy I suppose), and they often recommend the Cake Pattern instead.

If you’re interested in Scala and want to exchange ideas with other plugin developers, come join us at Atlascamp!
atlascamp.png

Fresh ideas, announcements, and inspiration for your team, delivered weekly.

Subscribe now

Fresh ideas, announcements, and inspiration for your team, delivered weekly.

Subscribe now