63

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?

Michael Neale
  • 19,248
  • 19
  • 77
  • 109

7 Answers7

40

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>

Michael Neale
  • 19,248
  • 19
  • 77
  • 109
  • Agreed that IntelliJ is the superior Scala IDE right now. With Odersky and Bonér working on Eclipse Scala IDE it should catch up eventually, but right now it's not nearly as good as IntelliJ –  Jun 28 '11 at 20:31
  • Sounds good! In maven I then type `mvn idea:idea` to have an IntelliJ project. From the IDE, when I right click on src/main/java/ or src/main/scala/ I do not have the option to create a new Scala Class or Object (only java stuff is displayed). How do I fix this? – Marsellus Wallace Aug 11 '12 at 19:54
  • 13
    I know this post is old but still shows up on Google, so I'll say that you don't need to add the scala-tools repository anymore. All the stuff you need is in central. – David Jan 09 '13 at 21:07
  • will the scala compiler use the `java` compiler version specified at `1.51.5`? thanks – Jas Dec 14 '14 at 15:18
  • Newest versions might require Java 8 and fail mysteriously if you try to use Java 7 or lower (`Predicate` class not found etc.). – berezovskyi Dec 27 '16 at 13:13
12

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.

sblundy
  • 60,628
  • 22
  • 121
  • 123
  • 1
    Can the scala code call java source in the same module and vice versa? When I am in intelliJ - it shows it all together anyway, so its not a huge deal. – Michael Neale Dec 03 '08 at 04:23
  • Oh and will this hook in to mvn compile etc? (I can see how scala:compile works). – Michael Neale Dec 03 '08 at 04:24
  • 2
    First of all, Java and Scala files can be in the same module. And second, they can be also in the same sources directory. You just have to set the maven option configuration->sourceDir of the scala plugin to tell maven where the source files are. – Stefan Endrullis Apr 01 '11 at 12:27
  • for using maven plugin for scala here is a nice guide. http://faisalbhagat.blogspot.com/2014/01/maven-with-scala.html – faisalbhagat Jan 08 '14 at 06:23
8

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
...
Community
  • 1
  • 1
lindelof
  • 34,556
  • 31
  • 99
  • 140
4

Look at Sonatype Maven Cookbook Chapter 3. Scala and Maven

cetnar
  • 9,357
  • 2
  • 38
  • 45
2

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.

Guðmundur Bjarni
  • 4,082
  • 1
  • 18
  • 14
  • I have had some success with http://scala-tools.org/mvnsites/maven-scala-plugin/ for the moment - not sure if that is what you were referring to or not. – Michael Neale Dec 04 '08 at 11:25
1

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>
Mebin
  • 109
  • 1
  • 2
  • 9
0

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>
BenMorel
  • 34,448
  • 50
  • 182
  • 322
Julian Dehne
  • 83
  • 1
  • 3