I have a Maven project with Kotlin code hello.kt
which calls Java code JavaFoo.java
which calls Kotlin code KotlinFoo.kt
. hello.kt
also calls KotlinFoo.kt
directly. I'm trying to build this with mvn clean install
using exactly the Maven settings described in kotlinlang's Maven docs.
If hello.kt
doesn't call JavaFoo
(but I leave JavaFoo
in the project) then this builds just fine.
The docs say that the Kotlin compiler should be invoked before the Java compiler, which suggests to me that all Kotlin code needs to compile before any Java code, i.e. with this setup you can call Kotlin from Java but not vice versa. However, the docs describe this setup as just "mixed code applications", not "calling Kotlin from Java".
In other words, this failure seems consistent with what the docs seem to imply but not with what they directly say -- or I'm just misunderstanding something.
I want to call each language from the other. Is there a Maven configuration that will do this, please?
(I looked at various StackExchange questions on mixed code settings and none of the solutions works for me.)
Adding the code as requested: pom.xml:
<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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example.kotlindemo</groupId>
<artifactId>kotlin-demo</artifactId>
<packaging>jar</packaging>
<version>1.0-SNAPSHOT</version>
<name>kotlin-demo</name>
<properties>
<kotlin.version>1.1.2-2</kotlin.version>
<kotlin.compiler.incremental>true</kotlin.compiler.incremental>
<main.class>com.example.kotlindemo.HelloKt</main.class>
</properties>
<dependencies>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-stdlib</artifactId>
<version>${kotlin.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<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>
<configuration>
<sourceDirs>
<sourceDir>${project.basedir}/src/main/kotlin</sourceDir>
<sourceDir>${project.basedir}/src/main/java</sourceDir>
</sourceDirs>
</configuration>
</execution>
<execution>
<id>test-compile</id>
<goals> <goal>test-compile</goal> </goals>
<configuration>
<sourceDirs>
<sourceDir>${project.basedir}/src/test/kotlin</sourceDir>
<sourceDir>${project.basedir}/src/test/java</sourceDir>
</sourceDirs>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<executions>
<!-- Replacing default-compile as it is treated specially by maven -->
<execution>
<id>default-compile</id>
<phase>none</phase>
</execution>
<!-- Replacing default-testCompile as it is treated specially by maven -->
<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>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.6</version>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals> <goal>single</goal> </goals>
<configuration>
<archive>
<manifest>
<mainClass>${main.class}</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
src/main/kotlin/hello.kt
:
package com.example.kotlindemo
fun main(args : Array<String>) {
println("Hello, world!")
var kfoo = KotlinFoo()
kfoo.printFooString()
kfoo.fooString = "init2"
kfoo.printFooString()
var foo2 = JavaFoo("abcd")
foo2.printString()
}
src/main/kotlin/KotlinFoo.kt
:
package com.example.kotlindemo
class KotlinFoo {
var fooString = "init"
fun printFooString() {
println(this.fooString)
}
}
src/main/java/JavaFoo.java
:
package com.example.kotlindemo;
class JavaFoo {
private KotlinFoo k;
JavaFoo(String initializer) {
k = new KotlinFoo();
k.setFooString(initializer);
}
void printString() {
this.k.printFooString();
}
}
Error:
[ERROR] .../src/main/kotlin/hello.kt: (12, 14) Unresolved reference: JavaFoo
Please make sure that you add the id 'kotlin-android-extensions' line on the build. gradle file that's inside your app module. Once you sync the Gradle build, the error should disappear.
If you still prefer to stick with good old Maven, there is no problem. There is a plugin for it to support Kotlin as well. If you don't have Maven on your machine, you can follow the instructions at https://maven.apache.org/install.html to get it installed on your local machine.
The kotlin-maven-plugin compiles Kotlin sources and modules. Currently, only Maven v3 is supported.
The compilation fails because your Java class is not in a directory that matches its package statement. While Kotlin allows you to put classes in any directories regardless of the package they're in, Java requires you to put each file in a package that corresponds to its directory. This requirement applies to mixed-language projects as well.
To fix the error, move JavaFoo.java
to src/main/java/com/example/kotlindemo
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With