如何指定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-compile
和default-testCompile
是特殊的,因为它们是内置的,所以它们总是首先执行。 上面的配置通过禁用默认的编译执行来解决这个问题,并且在kotlin-maven-plugin
之后使用新的编译执行来声明maven-compiler-plugin
kotlin-maven-plugin
。 通过这种方式,您可以在compile
生命周期的compile
阶段获得所有编译。
一个简单而有效的解决方案是改变应用于Kotlin Maven插件执行的两个阶段( <phase>
元素),从compile
到process-sources
,从test-compile
到process-test-sources
。
您希望Kotlin部分在Java之前执行。 默认情况下,Maven将调用Maven Compiler插件作为源代码compile
阶段的一部分,并为测试代码进行测试编译。 把Kotlin部分移到他们以前的阶段,然后按照你的意愿进行流动。
如果你想要相反的(首先Java然后Kotlin),那么你可以把Kotlin部分移到下一个阶段(例如:从compile
到process-classes
,从test-compile
到process-test-classes
)。
有关Maven阶段的更多详细信息,请查看官方文档 。
如果您打算使用不同的构建系统,可以使用Kobalt轻松设置依赖项目:
val p1 = javaProject { ... } val p2 = kotlinProject(p1) { ... }
这使得项目p2
依赖于p1
。 您也可以混合使用Java和Kotlin项目。