Kotlin with Maven

Java, kotlin, maven, programming

Stand-alone Programs

Instructions and template for a stand-alone Java program built with Kotlin source code.

An easy way to start with is, since JetBrains is behind this whole thing, just install and run their IntelliJ IDEA and create a new project from IntelliJ with the language set to Kotlin and build system set to Maven. Check the option to include a sample code. It should then flesh out a template project.

In the generated pom.xml file, make these modifications:

  • Add a property main.class that defines the main entry class to the generated MainKt class (so you don’t have to copy and paste into places).
  • Modify the exec-maven-plugin‘s mainClass to be ${main.class}.
  • Add the maven-assembly-plugin so that a stand-alone JAR will be created to be run.
  • Optional: Add the maven-compiler-plugin if you have Java code alongside Kotlin code.
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns="http://maven.apache.org/POM/4.0.0"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    ...
    <properties>
        ...
        <main.class>MainKt</main.class>
    </properties>

    ...

    <build>
        <sourceDirectory>src/main/kotlin</sourceDirectory>
        <testSourceDirectory>src/test/kotlin</testSourceDirectory>
        <plugins>
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>exec-maven-plugin</artifactId>
                <version>1.6.0</version>
                <configuration>
                    <mainClass>${main.class}</mainClass>
                </configuration>
            </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>3.4.2</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>

Building

Just running mvn install should build the stand-alone JAR:

  • target/<your project name>-1.0-SNAPSHOT-jar-with-dependencies.jar

Running

As a stand-alone JAR

To run the stand-alone JAR as a Java program:

java -jar target/<project name>-1.0-SNAPSHOT-jar-with-dependencies.jar ...

where ... are any arguments (args) you want to pass to the program.

With Maven

Because by default IntelliJ added the plugin exec-maven-plugin, the program can also be run without having to build the JAR. This is useful during development before deployment:

mvn exec:java -Dexec.args="..."

Notice that passing arguments to the program is a bit cumbersome due to the way Maven works (using the -Dexec.args property).

Deployment

The easiest way to deploy is to copy that target/<project name>-1.0-SNAPSHOT-jar-with-dependencies.jar to where you want to deploy the program. Renaming the JAR file to be something shorter helps. Also: changing the version in the POM file to a production SemVer value will get rid of that “SNAPSHOT” suffix.