Wednesday, December 27, 2006

Ant builds

We have a standardized ant build file(s) at work. There is usually not much thinking needed other than naming the project. If we used Scala regularly, we would need to incorporate the <scalac ... /> target into our buildfiles in such a way that it would transparently build Scala code if it existed. It is also important that the build succeed in one pass with no manual intervention for the CI server to perform its automated builds.

How can we structure our code and build files to satisfy this requirement? Scala code and freely call Java code (and vice-versa). In our build files we need to call both javac and scalac in some particular order. If we call javac first, then code like following will fail because the java compiler cannot yet see the scala class when it executes.
--- Foo.java ---
public class Foo {
private Bar bar;
// ...
}

--- Bar.scala ---
class Bar {
// ...
}
Of course, you have the reverse situation if you call scalac first, with same-project Java code invisible to the Scala compiler. A post to the Scala mailing list brought the following suggestion:
--- Foo.java ---
public class Foo {
private Bar bar;
// ...
}

--- Bar.java ---
public interface Bar {
// ...
}

--- BarImpl.scala ---
class BarImpl() extends Bar {
// ...
}

This allows us to statically reference a Java interface from Java code and to implement the class in Scala. Instances can be created at runtime, using the container (EJB, Spring, or JSF) or by using
Class.forName("package.BarImpl").newInstance();

Of course, we can still easily reference our Java object from Scala.
--- Baz.scala ---
class Baz {
def doSomething(foo: Foo): Unit = {
// do something with our Java object Foo
}
def doSomethingElse(): Unit = {
// instantiate our own Java-defined object
foo = new Foo();
}
}

So, the plan is to require Java interfaces for any Scala objects that are referenced from Java code. Of course, many of the advantages from Scala come from using its type system and will only show if whole layers of an application are implemented in Scala. Luckily, most of our layers are hidden behind interfaces anyway.

Next I'd like to experiment with different types of container-instantiation of Scala classes.

No comments: