Estoy trabajando en un proyecto mixto de Java y Kotlin usando maven.
El problema que estoy enfrentando ahora es que maven-compiler-plugin
ejecuta antes de comstackr 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
En mi código fuente de Java, estoy haciendo reference a las classs escritas en kotlin. Pero javac se ejecuta antes de kotlinc. Por lo tanto, maven interrumpe con errores de compilation.
Mi pom (pom padre, yo uso submodules) se ve así:
<?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>
La documentation de Kotlin sobre el uso de Maven sugiere vincular explícitamente la kotlin-maven-plugin
a la fase de las process-sources
del process-sources
. Como maven-compiler-plugin
está ligado a la fase de compile
, el enlace de kotlin-maven-plugin
a la fase de las process-sources
del process-sources
hace funcionar primero.
<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>
Aunque es más detallado, puede comstackr las fonts Java y Kotlin en la fase de compile
con la siguiente configuration:
<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>
Normalmente, los complementos se ejecutan en el order en que se declaran en el POM, pero las ejecuciones de default-compile
y default-testCompile
son especiales porque están incorporadas, por lo que siempre van primero. La configuration anterior lo kotlin-maven-plugin
deshabilitando las ejecuciones de compilation pnetworkingeterminadas y declarando maven-compiler-plugin
con nuevas ejecuciones de compilation después de kotlin-maven-plugin
. De esta forma, puede get que toda la compilation ocurra correctamente durante la fase de compilation del ciclo de vida de la compilation.
Una solución simple pero efectiva sería cambiar las dos fases (el elemento <phase>
) aplicadas a las ejecuciones del Complemento Kotlin Maven, desde la compile
hasta process-sources
y desde test-compile
de test-compile
hasta process-sources
de test-compile
process-test-sources
.
Quiere que la parte de Kotlin se ejecute antes que la de Java. Maven invocará por defecto el Plugin Maven Compiler como parte de la fase de compile
para el código fuente, y test-compile
de testing para el código de testing. Mover la parte de Kotlin a sus fases previas haría el flujo como lo deseara.
Si quería lo contrario (primero Java luego Kotlin), podría haber movido la parte de Kotlin a las siguientes fases (por ejemplo: de compile
a process-classes
y de test-compile
de test-compile
process-classes
de test-compile
process-test-classes
).
Para get más información sobre las fases de Maven, consulte la documentation oficial .
En caso de que esté abierto a utilizar un sistema de compilation diferente, los proyectos dependientes son fáciles de configurar con Kobalt :
val p1 = javaProject { ... } val p2 = kotlinProject(p1) { ... }
Esto hace que el proyecto p2
dependa de p1
. También puede mezclar proyectos de Java y Kotlin.