如何在Maven 3中指定同一阶段绑定的插件顺序?

7
我有一个使用Maven 3的多模块Scala项目。 我想确保在编译和测试编译阶段中,Scala编译器运行在Java编译器之前。
我已经尝试在父POM和模块POM中,在构建部分列出插件,以便Scala编译器插件排在首位,但是Maven仍然坚持先运行Java编译器,这在一些混合源的情况下会失败。
我知道我可以通过将Scala编译绑定到process-resources而不是compile来解决这个问题,但我真的更喜欢知道如何告诉Maven排序插件(或者是否可能)。
这是我的父POM中定义这两个插件的部分内容:
        <plugin>
            <groupId>org.scala-tools</groupId>
            <artifactId>maven-scala-plugin</artifactId>
            <version>2.15.2</version>
            <configuration>
                <scalaVersion>${scala.version}</scalaVersion>
            </configuration>
            <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>
            </executions>
        </plugin>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>2.3.2</version>
            <configuration>
                <source>1.6</source>
                <target>1.6</target>
            </configuration>
        </plugin>

子模块有自己的<plugins>部分,但没有重新定义这些插件(只是exec-maven-plugin)。


有效的 POM 文件中指定的顺序是什么? - Donal Fellows
项目位于 https://github.com/GrahamLea/SodaTest ,如果有人想克隆它并尝试修复,可以前往该网址。问题出现在 sodatest-examples-basic-java 模块中。(请注意,在提交的版本中一切正常,因为我将 Scala 编译绑定到了处理资源阶段。) - Graham Lea
@Donal:在模块的有效POM中(位于构建内部的插件部分),maven-scala-plugin出现在maven-compiler-plugin之前。插件管理部分在这里起了作用吗?这两个插件都没有出现在那里。 - Graham Lea
嗯,这与我理解的POM中的顺序相反,但无可奈何。 :-( 我想你可以尝试将其绑定到generate-sources阶段,这有点滥用,但如果有效的话... - Donal Fellows
4个回答

7

Maven开发团队已确认,目前无法完全控制插件在某个阶段内的执行顺序,除非编写自己的自定义生命周期并使用自定义包类型。

我已经在JIRA中创建了一个增强请求,希望他们考虑解决这个问题。如果您也有此问题,请投票支持。

目前似乎针对这个特定问题(混合Java / Scala编译),最佳实践的解决方法是将scala:compile绑定到process-resources,将scala:testCompile绑定到process-test-resources,如http://scala-tools.org/mvnsites/maven-scala-plugin/example_java.html所述。


1

编译一个混合的Java/Scala项目,实际上比仅仅编译其中一个再编译另一个要复杂一些。Scala编译器能够解析Java文件,以匹配你从Scala中使用的任何Java类的签名。编译器可以在这里为你做正确的事情,但你必须首先告诉它这样做。

最好使用SBT而不是Maven,因为它将提供许多优点,超出了仅仅得到正确的编译顺序。

如果放弃Maven不是一个选项,那么请按照maven-scala-plugin的配置说明进行操作,链接在此处:http://scala-tools.org/mvnsites/maven-scala-plugin/example_java.html


嗨,Kevin。感谢您的评论。在Maven中,实际上并不比一个接一个地编译更复杂。Scala插件默认配置了所有源路径,因此它“只需运行”。不幸的是,Maven中存在一个错误,阻止插件顺序受用户控制。您的链接显示了解决方法的配置,这是目前最好的解决方案。祝好,Graham。 - Graham Lea

1

您可以同时运行两个独立的目标,Maven 将按顺序执行这些目标:

mvn scala:compile compiler:compile

谢谢。这是一个有趣的想法,它可以工作,但那样项目就不能为那些不知道他们必须这样做的人构建。开源Maven项目 - 人们期望(正确地)能够运行mvn install并使其全部工作。 - Graham Lea
+1 for scala:compile。好处是,如果你在混合使用Java和Scala,Scala编译器插件也会编译Java文件。因此,一个简单的 mvn scala:compile 就可以完成工作。 - FUD

-1

这个 id 是否是用于 Maven 编译插件的 default-compile?如果不是,你可以设置一下并尝试一下是否有效吗?

如果不行,你可以更新问题并提供相关的 pom 片段和 Maven 运行的片段。


我猜你是指执行的ID吧?实际上,对于标准编译插件,我没有任何执行,所以我添加了一些,使用你指定的ID和相应的测试树ID,但这并没有帮助。 - Graham Lea

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