Minimal example of a Maven pom for a mixed Kotlin and Java project

August 18, 2021 [Java, Kotlin, Maven, Programming, Tech]

The Kotlin docs describe some things you need in your pom.xml to create a project that is a mix of Kotlin and Java code, but there is no complete example, so here is mine:

pom.xml:

<project>
<modelVersion>4.0.0</modelVersion>

&lt;groupId&gt;com.example.kj&lt;/groupId&gt;
&lt;artifactId&gt;kotlin-and-java&lt;/artifactId&gt;
&lt;version&gt;1.0.0-SNAPSHOT&lt;/version&gt;

&lt;properties&gt;
    &lt;kotlin.version&gt;1.5.21&lt;/kotlin.version&gt;
    &lt;project.build.sourceEncoding&gt;UTF-8&lt;/project.build.sourceEncoding&gt;
    &lt;project.reporting.outputEncoding&gt;UTF-8&lt;/project.reporting.outputEncoding&gt;
&lt;/properties&gt;

&lt;build&gt;
    &lt;plugins&gt;
        &lt;plugin&gt;
            &lt;groupId&gt;org.jetbrains.kotlin&lt;/groupId&gt;
            &lt;artifactId&gt;kotlin-maven-plugin&lt;/artifactId&gt;
            &lt;version&gt;${kotlin.version}&lt;/version&gt;
            &lt;executions&gt;
                &lt;execution&gt;
                    &lt;id&gt;compile&lt;/id&gt;
                    &lt;goals&gt;
                        &lt;goal&gt;compile&lt;/goal&gt;
                    &lt;/goals&gt;
                    &lt;configuration&gt;
                        &lt;sourceDirs&gt;
                            &lt;sourceDir&gt;${project.basedir}/src/main/kotlin&lt;/sourceDir&gt;
                            &lt;sourceDir&gt;${project.basedir}/src/main/java&lt;/sourceDir&gt;
                        &lt;/sourceDirs&gt;
                    &lt;/configuration&gt;
                &lt;/execution&gt;
                &lt;execution&gt;
                    &lt;id&gt;test-compile&lt;/id&gt;
                    &lt;goals&gt; &lt;goal&gt;test-compile&lt;/goal&gt; &lt;/goals&gt;
                    &lt;configuration&gt;
                        &lt;sourceDirs&gt;
                            &lt;sourceDir&gt;${project.basedir}/src/test/kotlin&lt;/sourceDir&gt;
                            &lt;sourceDir&gt;${project.basedir}/src/test/java&lt;/sourceDir&gt;
                        &lt;/sourceDirs&gt;
                    &lt;/configuration&gt;
                &lt;/execution&gt;
            &lt;/executions&gt;
        &lt;/plugin&gt;
        &lt;plugin&gt;
            &lt;groupId&gt;org.apache.maven.plugins&lt;/groupId&gt;
            &lt;artifactId&gt;maven-compiler-plugin&lt;/artifactId&gt;
            &lt;version&gt;3.5.1&lt;/version&gt;
            &lt;executions&gt;
                &lt;!-- Replacing default-compile as it is treated specially by maven --&gt;
                &lt;execution&gt;
                    &lt;id&gt;default-compile&lt;/id&gt;
                    &lt;phase&gt;none&lt;/phase&gt;
                &lt;/execution&gt;
                &lt;!-- Replacing default-testCompile as it is treated specially by maven --&gt;
                &lt;execution&gt;
                    &lt;id&gt;default-testCompile&lt;/id&gt;
                    &lt;phase&gt;none&lt;/phase&gt;
                &lt;/execution&gt;
                &lt;execution&gt;
                    &lt;id&gt;java-compile&lt;/id&gt;
                    &lt;phase&gt;compile&lt;/phase&gt;
                    &lt;goals&gt;
                        &lt;goal&gt;compile&lt;/goal&gt;
                    &lt;/goals&gt;
                &lt;/execution&gt;
                &lt;execution&gt;
                    &lt;id&gt;java-test-compile&lt;/id&gt;
                    &lt;phase&gt;test-compile&lt;/phase&gt;
                    &lt;goals&gt;
                        &lt;goal&gt;testCompile&lt;/goal&gt;
                    &lt;/goals&gt;
                &lt;/execution&gt;
            &lt;/executions&gt;
        &lt;/plugin&gt;
    &lt;/plugins&gt;
&lt;/build&gt;
&lt;dependencies&gt;
    &lt;dependency&gt;
        &lt;groupId&gt;org.jetbrains.kotlin&lt;/groupId&gt;
        &lt;artifactId&gt;kotlin-stdlib&lt;/artifactId&gt;
        &lt;version&gt;${kotlin.version}&lt;/version&gt;
    &lt;/dependency&gt;
&lt;/dependencies&gt;

</project>

src/main/java/MyJava.java:

public class MyJava {
public static void main(String[] args) {
MyKotlin k = new MyKotlin();  // Use Kotlin from Java
System.out.println(k.message());
}
}

src/main/kotlin/MyKotlin.kt:

class MyKotlin : MyJava() {  // Use Java from Kotlin
fun message(): String {
return "Hello from Kotlin!"
}
}

src/test/java/MadeInJavaTest.java:

class MadeInJavaTest {
public void testCanUseJava() {
MyJava j = new MyJava();
}

public void testCanUseKotlin() {
    MyKotlin k = new MyKotlin();
    assertEquals(k.message(), "Hello from Kotlin!");
}

static void assertEquals(String left, String right) {
    if (!left.equals(right)) {
        throw new AssertionError(left + " != " + right);
    }
}

}

src/test/kotlin/MadeInKotlinTest.kt:

class MadeInKotlinTest {
fun testCanUseJava() {
MyJava()
}

fun testCanUseKotlin() {
    val k = MyKotlin();
    assertEquals(k.message(), "Hello from Kotlin!");
}

}

fun assertEquals(left: String, right: String) { if (left != right) { throw AssertionError("${left} != ${right}"); } }