Building a scala app with maven (that has java source mixed in)
I have an application where I would like to have mixed Java and Scala source (actually its migrating a java app to scala - but a bit at a time).
I can make this work in IDEs just fine, very nice. But I am not sure how to do this with maven - scalac can compile java and scala intertwined, but how to I set up maven for the module?
Also, does my scala source have to be a different folder to the java?
Using the maven scala plugin, a config like the one below will work for a project that mixes java and scala source (scala source of course goes in the /scala directory, as mentioned by someone else).
You can run run mvn compile, test etc... and it will all work as normal. Very nice (it will run scalac first automatically).
For a great IDE, IntelliJ 8 works nicely: add in the scala plug in, then add a scala facet, and then adjust the compile setting for scala to run scalac first (critical if you have circular dependencies with scala and java source).
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>demo</groupId>
<artifactId>scala-java-app</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>scala-java-app</name>
<repositories>
<repository>
<id>scala-tools.org</id>
<name>Scala-tools Maven2 Repository</name>
<url>http://scala-tools.org/repo-releases</url>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>scala-tools.org</id>
<name>Scala-tools Maven2 Repository</name>
<url>http://scala-tools.org/repo-releases</url>
</pluginRepository>
</pluginRepositories>
<build>
<plugins>
<plugin>
<groupId>org.scala-tools</groupId>
<artifactId>maven-scala-plugin</artifactId>
<executions>
<execution>
<id>compile</id>
<goals>
<goal>compile</goal>
</goals>
<phase>compile</phase>
</execution>
<execution>
<id>test-compile</id>
<goals>
<goal>testCompile</goal>
</goals>
<phase>test-compile</phase>
</execution>
<execution>
<phase>process-resources</phase>
<goals>
<goal>compile</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.5</source>
<target>1.5</target>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.scala-lang</groupId>
<artifactId>scala-library</artifactId>
<version>2.7.2</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
Yeah, the scala part has to be in a separate module and in src/main/scala
directory. Maven regards mixed source like this as heresy.
You enable scala compilation by importing the scala maven plugin. The "usage" page as a good example.
I once asked a very similar question about how to include non-Java code in a Maven project. The gist of the answer was to have under src a different directory for each programming language, and to find/write a Maven plugin that would know what to do with each. Eg:
src/
|-- main
| |-- bin
| |-- sh
| |-- sql
| |-- scala
| |-- java
| `-- resources
|-- site
...
Look at Sonatype Maven Cookbook Chapter 3. Scala and Maven
I solved this some time ago by having one Maven module written in Scala and the other in Java. But since Scala and Java can cross depend on one another (Java -> Scala -> Java or the other way around), then this is something very desirable without multi module projects.
There is work underway in solving this, you can read about it here and a new version of the maven-scala-plugin will be released soon.