【问题标题】:Maven: mixing Java and Scala in one projectMaven:在一个项目中混合 Java 和 Scala
【发布时间】:2016-02-23 13:03:43
【问题描述】:

今天我一直在尝试找到一个合适的解决方案来设置一个包含 Java 和 Scala 代码(它们之间具有双向依赖关系)的 maven 项目。

我发现的解决方案通常包括在process-resources 阶段调用 scala-maven-plugin 或 maven-scala-plugin 以便它在默认的 maven 编译器插件之前运行(例如:http://www.hascode.com/2012/03/snippet-mixing-scala-java-in-a-maven-project/https://itellity.wordpress.com/2014/08/21/mixing-scala-and-java-in-a-maven-project/ , scala-maven-plugin 官方页面:http://davidb.github.io/scala-maven-plugin/example_java.html)。

这导致了如下所示的解决方案:

<build>
    <plugins>
        <plugin>
            <groupId>net.alchim31.maven</groupId>
            <artifactId>scala-maven-plugin</artifactId>
            <recompileMode>incremental</recompileMode>
            <executions>
                <execution>
                    <id>scala-compile</id>
                    <phase>process-resources</phase>
                    <goals>
                        <goal>add-source</goal>
                        <goal>compile</goal>
                    </goals>
                </execution>
                <execution>
                    <id>scala-test-compile</id>
                    <phase>process-test-resources</phase>
                    <goals>
                        <goal>testCompile</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

此解决方案运行良好 - Scala 编译在 process-resources 阶段调用,它编译 Java 和 Scala 代码,因此当 maven 编译器插件在 compile 阶段运行时,.class 文件已准备就绪。

问题是这个解决方案在我看来并不干净。在编译阶段之前调用 Scala 编译过程只是为了确保它在 maven 编译器插件看起来“hacky”之前运行。

Scala 编译器无论如何都会编译 Java 类,所以我想我可以完全关闭默认的 maven 编译器插件,然后 Scala 编译器可以在compile 阶段运行。虽然配置有点长,但对我来说看起来更干净:

<build>
    <plugins>
        <plugin>
            <groupId>net.alchim31.maven</groupId>
            <artifactId>scala-maven-plugin</artifactId>
            <recompileMode>incremental</recompileMode>
            <executions>
                <execution>
                    <id>scala-compile</id>
                    <phase>compile</phase>
                    <goals>
                        <goal>add-source</goal>
                        <goal>compile</goal>
                    </goals>
                </execution>
                <execution>
                    <id>scala-test-compile</id>
                    <phase>test-compile</phase>
                    <goals>
                        <goal>testCompile</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        <plugin>
            <artifactId>maven-compiler-plugin</artifactId>
            <executions>
                <execution>
                    <id>default-compile</id>
                    <phase>none</phase>
                </execution>
                <execution>
                    <id>default-testCompile</id>
                    <phase>none</phase>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

我想知道为什么这个解决方案不是博客文章或官方插件页面上建议的解决方案。这种方法有什么缺点吗?使用第二种解决方案而不是第一种解决方案有什么问题吗?

【问题讨论】:

    标签: java scala maven scala-maven-plugin


    【解决方案1】:
    • 是的,解决方案是“hacky”,但 maven-compiler-plugin 始终是在编译阶段运行的第一个插件(就像硬编码到 maven 中一样)。
    • 我没有使用 scala 2.11 进行测试,但之前版本的 scalac 不会将 .java 编译成 .class(仅解析它们)。自 2.7 起,scala-maven-plugin 可与“每个版本的 scala”一起运行。

    【讨论】:

    • 谢谢,很高兴能从插件作者本人那里得到答案 :-) 我没有考虑向后兼容性。看起来 Scala 编译器从 Scala 2.7.2 (codecommit.com/blog/scala/…) 开始编译 Java 文件。我用不同的 Scala 版本测试了“我的”解决方案,并确认它只适用于 Scala >=2.7.2。
    • 我猜你错过了阅读这篇文章,scalac 不编译 java 但能够阅读它。 (并且 iirc 仅适用于 .scala 使用的类)。无论如何,如果它现在有效,很高兴知道。 (我更喜欢更短的解决方案和定义编译的java选项的能力)
    • 你说得对,我误读了一篇文章,而且我的测试也不正确(我认为它有效,因为它没有抛出任何错误,但那是因为 scala 编译器可以,如你所说,解析java文件并读取它们的API)。看起来只有当插件配置为 incremental 以便它使用独立的锌编译器时,该解决方案才能正常工作。 Zinc 似乎能够同时编译 java 和 scala,这就是它工作的原因,至少在最新的 scala 版本中是这样。感谢您的参与,很抱歉造成混淆:-)
    猜你喜欢
    • 1970-01-01
    • 2012-08-24
    • 2018-03-08
    • 2011-05-25
    • 2014-08-18
    • 2011-12-08
    • 2011-01-04
    • 2021-10-25
    • 1970-01-01
    相关资源
    最近更新 更多