使用Maven构建一个包含Java源代码的Scala应用程序

63
我有一个应用程序,希望使用混合的Java和Scala源代码(实际上是将Java应用程序逐步迁移到Scala)。
在IDE中,我可以轻松地使其正常工作。但是,我不确定如何在maven中设置 - scalac可以编译交织的Java和Scala源代码,但是我该如何为模块设置Maven?
另外,我的Scala源代码必须与Java放在不同的文件夹中吗?
7个回答

40

使用Maven Scala插件,像下面这样的配置可以用于混合Java和Scala源码的项目(Scala源码当然放在/scala目录中,正如其他人所提到的)。

你可以运行mvn compile、test等指令,它们都会按照正常的方式工作。非常棒(它会自动先运行scalac)。

对于一个出色的IDE,IntelliJ 8很好用:添加Scala插件,然后添加Scala Facet,最后将Scala的编译设置调整为首先运行scalac(如果你有Scala和Java源代码之间的循环依赖关系,则此步骤至关重要)。

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


目前 IntelliJ 是最优秀的 Scala IDE,这一点是毋庸置疑的。虽然 Odersky 和 Bonér 正在开发 Eclipse Scala IDE,但它还需要一些时间才能赶上 IntelliJ 的水平。因此,目前 IntelliJ 仍然是首选。 - user23987
好的!在Maven中,我输入mvn idea:idea来创建一个IntelliJ项目。从IDE中,当我右键单击src/main/java/或src/main/scala/时,我没有创建新的Scala类或对象的选项(只显示Java相关内容)。我该如何解决这个问题? - Marsellus Wallace
13
我知道这篇文章已经有些年头了,但它仍然出现在谷歌上,所以我来说一下:你不需要再添加scala-tools仓库了。你需要的全部都在中央仓库里。 - David
Scala编译器会使用在<source>1.5</source><target>1.5</target>中指定的Java编译器版本吗?谢谢。 - Jas
最新版本可能需要Java 8,如果您尝试使用Java 7或更低版本,则可能会出现神秘的失败(例如找不到“Predicate”类)。 - berezovskyi

12

是的,Scala部分必须在一个单独的模块中,并且放置于src/main/scala目录下。Maven认为这样混合使用源码是不可接受的。

你可以通过导入Scala Maven插件来启用Scala编译。该插件的"usage"页面提供了很好的例子。


1
Scala代码能否调用同一模块中的Java源代码,反之亦然? 当我在IntelliJ中时,它会将其全部显示在一起,所以这并不是一个很大的问题。 - Michael Neale
哦,这个能够与mvn compile等集成吗?(我知道scala:compile是如何工作的) - Michael Neale
2
首先,Java和Scala文件可以在同一个模块中。其次,它们也可以在同一个源目录中。您只需要设置Scala插件的maven选项配置->sourceDir,告诉maven源文件的位置即可。 - Stefan Endrullis
使用Maven插件进行Scala编程,这里有一个不错的指南。http://faisalbhagat.blogspot.com/2014/01/maven-with-scala.html - faisalbhagat

8

我曾经问过一个非常相似的问题,关于如何在Maven项目中包含非Java代码。回答的要点是在src下为每种编程语言创建不同的目录,并找到/编写一个Maven插件来处理每个目录下的代码。例如:

src/
|-- main
|   |-- bin
|   |-- sh
|   |-- sql
|   |-- scala
|   |-- java
|   `-- resources
|-- site
...

4

2
我之前解决过这个问题,方法是将一个Maven模块用Scala编写,另一个用Java编写。由于Scala和Java可以相互依赖(Java -> Scala -> Java或者反过来),因此这是非常理想的,不需要多模块项目。
目前正在解决这个问题,你可以在这里阅读相关信息,并且maven-scala-plugin的新版本即将发布。

我目前在使用http://scala-tools.org/mvnsites/maven-scala-plugin/ 工具上有一些成功的经验 - 不确定这是否是你所提到的工具。 - Michael Neale

1
这是一个使用scala、java和mongo db完成的小项目链接(https://github.com/mebinjacob/mongo-scala-java-maven-poc)。
请注意,在项目的pom.xml中,可以指定scala文件的源文件夹,它可以与java相同,也可以是不同的文件夹,例如src/main/scala。Scala类没有必要放在单独的src文件夹中。我尝试过两种方法,它们都非常好用。我所提到的pom片段如下:
    <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>

0

你需要结合几种方法才能自由地混合Scala和Java类。 这个解决方案对我很有效:

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接