如何指定maven编译器插件的顺序

我正在使用maven开发一个混合的java和kotlin项目。

我现在面临的问题是, maven-compiler-plugin在编译kotlin-maven-plugin之前运行。

 [INFO] --- maven-compiler-plugin:3.0:compile (default-compile) @annotation --- [INFO] Changes detected - recompiling the module! [INFO] Compiling 11 source files to /Users/hannes/workspace/tikxml/annotation/target/classes [INFO] --- kotlin-maven-plugin:1.0.0-beta-4583:compile (compile) @ annotation [INFO] Kotlin Compiler version 1.0.0-beta-4583 

在我的java源代码中,我引用了用kotlin编写的类。 但是javac在kotlinc之前运行。 因此,maven中断与编译器错误。

我的POM(父POM,我使用子模块)看起来像这样:

 <?xml version="1.0" encoding="UTF-8"?> <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/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.sonatype.oss</groupId> <artifactId>oss-parent</artifactId> <version>7</version> </parent> ... <modules> <module>core</module> <module>annotation</module> <module>processor</module> </modules> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <java.version>1.7</java.version> <kotlin.version>1.0.0-beta-4583</kotlin.version> </properties> <build> <pluginManagement> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.0</version> <configuration> <source>${java.version}</source> <target>${java.version}</target> </configuration> </plugin> </plugins> </pluginManagement> <plugins> <plugin> <groupId>org.jetbrains.kotlin</groupId> <artifactId>kotlin-maven-plugin</artifactId> <version>${kotlin.version}</version> <executions> <execution> <id>compile</id> <phase>compile</phase> <goals> <goal>compile</goal> </goals> <configuration> <sourceDirs> <source>src/main/java</source> </sourceDirs> </configuration> </execution> <execution> <id>test-compile</id> <phase>test-compile</phase> <goals> <goal>test-compile</goal> </goals> <configuration> <sourceDirs> <source>src/test/java</source> </sourceDirs> </configuration> </execution> </executions> </plugin> </plugins> </build> </project> 

关于使用Maven的Kotlin文档建议将kotlin-maven-plugin执行明确地绑定到process-sources阶段。 由于maven-compiler-plugin绑定到compile阶段,因此将kotlin-maven-plugin绑定到process-sources阶段使其首先运行。

 <plugin> <artifactId>kotlin-maven-plugin</artifactId> <groupId>org.jetbrains.kotlin</groupId> <version>${kotlin.version}</version> <executions> <execution> <id>compile</id> <phase>process-sources</phase> <goals> <goal>compile</goal> </goals> </execution> <execution> <id>test-compile</id> <phase>process-test-sources</phase> <goals> <goal>test-compile</goal> </goals> </execution> </executions> </plugin> 

尽管更详细,但可以在compile阶段使用以下配置来编译Java和Kotlin源代码:

 <plugin> <artifactId>kotlin-maven-plugin</artifactId> <groupId>org.jetbrains.kotlin</groupId> <version>${kotlin.version}</version> <executions> <execution> <id>kotlin-compile</id> <phase>compile</phase> <goals> <goal>compile</goal> </goals> </execution> <execution> <id>kotlin-test-compile</id> <phase>test-compile</phase> <goals> <goal>test-compile</goal> </goals> </execution> </executions> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.5</version> <executions> <execution> <id>default-compile</id> <phase>none</phase> </execution> <execution> <id>default-testCompile</id> <phase>none</phase> </execution> <execution> <id>java-compile</id> <phase>compile</phase> <goals> <goal>compile</goal> </goals> </execution> <execution> <id>java-test-compile</id> <phase>test-compile</phase> <goals> <goal>testCompile</goal> </goals> </execution> </executions> </plugin> 

通常情况下,插件是按照在POM中声明的顺序执行的,但是default-compiledefault-testCompile是特殊的,因为它们是内置的,所以它们总是首先执行。 上面的配置通过禁用默认的编译执行来解决这个问题,并且在kotlin-maven-plugin之后使用新的编译执行来声明maven-compiler-plugin kotlin-maven-plugin 。 通过这种方式,您可以在compile生命周期的compile阶段获得所有编译。

一个简单而有效的解决方案是改变应用于Kotlin Maven插件执行的两个阶段( <phase>元素),从compileprocess-sources ,从test-compileprocess-test-sources

您希望Kotlin部分在Java之前执行。 默认情况下,Maven将调用Maven Compiler插件作为源代码compile阶段的一部分,并为测试代码进行测试编译。 把Kotlin部分移到他们以前的阶段,然后按照你的意愿进行流动。

如果你想要相反的(首先Java然后Kotlin),那么你可以把Kotlin部分移到下一个阶段(例如:从compileprocess-classes ,从test-compileprocess-test-classes )。

有关Maven阶段的更多详细信息,请查看官方文档 。

如果您打算使用不同的构建系统,可以使用Kobalt轻松设置依赖项目:

 val p1 = javaProject { ... } val p2 = kotlinProject(p1) { ... } 

这使得项目p2依赖于p1 。 您也可以混合使用Java和Kotlin项目。