Building a scala app with maven (that has java source mixed in)

JavaMaven 2Scala

Java Problem Overview


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?

Java Solutions


Solution 1 - 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>

Solution 2 - Java

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.

Solution 3 - Java

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
...

Solution 4 - Java

Look at Sonatype Maven Cookbook Chapter 3. Scala and Maven

Solution 5 - Java

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.

Solution 6 - Java

Here's a small project link(https://github.com/mebinjacob/mongo-scala-java-maven-poc) that I did using scala, java and mongo db.

Note in the pom.xml of the project one can specify the source folder of scala files it can be same as that of java or a different folder like src/main/scala. There is no mandate for scala classes to be on a separate src folders. I have tried both of them and both of them work great. The snippet of the pom that I am referring to is

    <build>
	<plugins>
		<plugin>
			<groupId>org.scala-tools</groupId>
			<artifactId>maven-scala-plugin</artifactId>
			<executions>
				<execution>
					<goals>
						<goal>compile</goal>
						<goal>testCompile</goal>
					</goals>
				</execution>
			</executions>
			<configuration>
				<sourceDir>src/main/scala</sourceDir>
				<jvmArgs>
					<jvmArg>-Xms64m</jvmArg>
					<jvmArg>-Xmx1024m</jvmArg>
				</jvmArgs>
			</configuration>
		</plugin>
	</plugins>
</build>

Solution 7 - Java

You need to combine several approaches in order to mix scala and java classes freely. This solution worked for me:

   <properties>
		<maven.compiler.source>1.7</maven.compiler.source>
		<maven.compiler.target>1.7</maven.compiler.target>
		<!-- <encoding>UTF-8</encoding> -->
		<scala.tools.version>2.10</scala.tools.version>
		<scala.version>2.10.3</scala.version>
	</properties>
<build>
		<sourceDirectory>src/main/scala</sourceDirectory>
		<testSourceDirectory>src/test/scala</testSourceDirectory>
		<plugins>
			<plugin>
				<groupId>org.scala-tools</groupId>
				<artifactId>maven-scala-plugin</artifactId>
				<version>2.15.2</version>
				<executions>					
					<execution>
						<id>scala-compile-first</id>
						<phase>process-resources</phase>
						<goals>
							<goal>compile</goal>
						</goals>
					</execution>
					<execution>
						<id>scala-test-compile</id>
						<phase>process-test-resources</phase>
						<goals>
							<goal>testCompile</goal>
						</goals>
					</execution>
				</executions>
			</plugin>

			<plugin>				
				<groupId>net.alchim31.maven</groupId>
				<artifactId>scala-maven-plugin</artifactId>
				<version>3.1.3</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>
				</executions>
			</plugin>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-surefire-plugin</artifactId>
				<version>2.13</version>
				<configuration>
					<useFile>false</useFile>
					<disableXmlReport>true</disableXmlReport>				
					<includes>
						<include>**/*Test.*</include>
						<include>**/*Suite.*</include>
					</includes>
				</configuration>
			</plugin>		
		</plugins>
	</build>

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionMichael NealeView Question on Stackoverflow
Solution 1 - JavaMichael NealeView Answer on Stackoverflow
Solution 2 - JavasblundyView Answer on Stackoverflow
Solution 3 - JavalindelofView Answer on Stackoverflow
Solution 4 - JavacetnarView Answer on Stackoverflow
Solution 5 - JavaGuðmundur BjarniView Answer on Stackoverflow
Solution 6 - JavaMebinView Answer on Stackoverflow
Solution 7 - JavaJulian DehneView Answer on Stackoverflow