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?

Answers


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.


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>

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>

Need Your Help

how to generate salt in yii?

yii salt

I'm working on user management in my project and I got to the part where I need to store the passwords in the database. I read that the password should be crypt with the salt and be kept together.