Fast Scala Compilation with Maven

by 11/09/2012 09:36:00 AM 2 comments
If you've done any work with Scala, you quickly realize that the compiler can be rather, ahem, slow. (We're talking C++ compiler slow). Now, I'm not knocking the scala compiler, I realize it's doing a lot of work, so I forgive it. But still, I just want things to compile faster. Typesafe pushes sbt as the solution to slow compilation as it supports incremental compilation and reduced startup time (i.e You can launch sbt and keep it running; you don't have to spin up a JVM for every compile cycle.). However, I think Typesafe has finally realized that Maven is very popular as a Scala build tool and so have released zinc, which is just the standalone version of sbt's incremental compiler. I've found that combining zinc with mvnsh results in much, much, much faster compilation cycles than just plain Maven. Here's how to get it going ... oh, the instructions are for a Mac, but you'll get the gist of it.

Download and Install Zinc

If you have homebrew, run the following:
brew install zinc
Otherwise:
  1. Download zinc from https://github.com/typesafehub/zinc
  2. Extract the zip file
  3. cd into zinc-[version]/bin
  4. Start zinc from a terminal with zinc -start
  5. Note: when you're done with zinc you'll need to stop it with zinc -shutdown

Install mvnsh

Homebrew is again your friend ... just run the following:
brew install maven-shell
Otherwise, you can get the source and build mvnsh from https://github.com/jdillon/mvnsh

Configure your Maven project to use Zinc

At this point, I'm assuming you already have a pom.xml configured for building a scala project. If not you can just use mvn archetype:generate and select the 'simple scala project' template. That will give you a pom.xml file to work with. Make sure that the pom file is using the very excellent scala-maven-plugin; and tell the plugin to use zinc if it's available. So your pom include something like the snippet below ... Notice the line that has useZincServer; that's important to have:
<build>
    <plugins>
        <plugin>
            <groupId>net.alchim31.maven</groupId>
            <artifactId>scala-maven-plugin</artifactId>
            <version>3.1.0</version>
            <executions>
                <execution>
                    <goals>
                        <goal>compile</goal>
                        <goal>testCompile</goal>
                    </goals>
                    <configuration>
                        <args>
                            <arg>-make:transitive</arg>
                            <arg>-dependencyfile</arg>
                            <arg>${project.build.directory}/.scala_dependencies</arg>
                        </args>
                    </configuration>
                </execution>
                <execution>
                    <id>scala-test-compile</id>
                    <phase>process-test-resources</phase>
                    <goals>
                        <goal>testCompile</goal>
                    </goals>
                </execution>
            </executions>
            <configuration>
                <jvmArgs>
                    <jvmArg>-Xss2m</jvmArg>
                </jvmArgs>
                <recompileMode>incremental</recompileMode>
                <useZincServer>true</useZincServer>
            </configuration>
        </plugin>
    </plugins>
</build>

Building your Project

  1. Start zinc in a terminal (zinc -start)
  2. Start mvnsh in a terminal (mvnsh)
  3. In mvnsh, issue your build commands (e.g. mvn package)
Any builds from scratch (first builds, builds after 'mvn clean') will still take a relatively long time (coffee break!). But subsesquent builds will be much, much faster. If you forget to start zinc, no worries, maven will fall back to using the standard compiler.

Brian Schlining

Developer

Cras justo odio, dapibus ac facilisis in, egestas eget quam. Curabitur blandit tempus porttitor. Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor.

2 comments:

Ionuț G. Stan said...

Just wanted to point out that zinc is now available on homebrew, just as mvnsh. So: brew install zinc

Brian Schlining said...

Thanks for pointing that out. I've updated the post.