ZOFTINO.COM android and web dev tutorials

Creating Kotlin Jar Using Maven in Eclipse

In this tutorial, you can learn how to create Kotlin project which contains both java and kotlin code and package it as jar using Maven in Eclipse. We will use eclipse IDE, eclipse maven plug-in for dependency management and packaging, and eclipse kotlin plug-in for kotlin programming in eclipse.

First, install latest versions of JDK and eclipse, then make sure that eclipse maven plug-in is installed in eclipse and then create Java project following instructions described in using eclipse maven plug-in tutorial.

After maven java project has been created, add kotlin main source folder and test folder to the maven project by right clicking the project, then clicking new and add source folder menu items and entering source folder name.

java project add kotlin source

Then install eclipse kotlin plug-in for kotlin coding help. To do that go to Help menu, click Eclipse Marketplace menu item, search for kotlin and click install button of kotlin plugin item in the search results. After installation of the plug-in, it will ask for restart of eclipse, go ahead and restart eclipse.

Then add kotlin source fie to src/main/kotlin by right clicking project and then clicking new and other menu items, and then selecting kotlin file option. In the next window, enter package and kotlin file name.

Then add source to kotlin file. Our example kotlin class contains main function which prompts for name, invokes a method on java class which exists in src/main/java and prints the results.

package com.zoftino.kotlin.hello

import java.util.Scanner

fun main(args: Array<String>) {
	println("name: ");
	val input = Scanner(System.`in`)
    val name = input.next();
	val newName = App.nameCheck("$name");
	println("Hello $newName");
}

Here is the java class.

package com.zoftino.kotlin.hello;

public class App 
{
	public static String nameCheck(String in) {
		return in.toLowerCase();
	}
}

Then open pom.xml and add kotlin maven dependency to pom.xml file. If your code uses other dependencies, add them too.

  <dependency>
    <groupId>org.jetbrains.kotlin</groupId>
    <artifactId>kotlin-stdlib</artifactId>
    <version>1.2.51</version>
	</dependency>
  <dependency>

Then add build elements with source folders and reference to kotlin maven plug-in for compiling both kotlin and java code.

	<build>
	<pluginManagement>
		<plugins>
			<plugin>
				<artifactId>kotlin-maven-plugin</artifactId>
				<groupId>org.jetbrains.kotlin</groupId>
				<version>1.2.51</version>
				<executions>
					<execution>
						<id>compile</id>
						<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>
					<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>
		</plugins>
		</pluginManagement>
	</build>

Then add maven-jar-plugin entry under build > plugins element in pom xml for packaging our kotlin project as jar file. Add manifest entry to the configuration of maven-jar-plugin plug-in by specifying the main class which can be java or kotlin class.

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-jar-plugin</artifactId>
    <version>2.6</version>
    <configuration>
        <archive>
            <manifest>
                <addClasspath>true</addClasspath>
                <mainClass>${main.class}</mainClass>
            </manifest>
        </archive>
    </configuration>
</plugin>

After modifying the pom.xml, right click your kotlin project, click Maven, then click Update Project menu item and then click ok.

Now to package kotlin project as jar file, you need to right click the project and then click Run as and Run configuration menu items. In the next window, select project base directory, enter maven goal and enter run configuration name, apply and click run to create jar.

maven run configuration

Here is the output of packaging kotlin as jar using maven in eclipse.

kotlin maven eclipse build output

Here is the project structure after the maven build in eclipse.

eclipse kotlin maven jar project structure

You can run the jar inside eclipse. To do that, first click Run menu, then click External Tools and External Tools Configuration menu items.

run jar in eclipse

In the External Tools Configuration window, enter configuration name, java exe location and working directory where jar located and in the arguments, enter –jar option with full path of the jar you want to execute, in our case the jar exists in the target directory. Then click apply and run.

eclipse external tools configuration to run jar

After running the jar, you will get following error.

Exception in thread "main" java.lang.NoClassDefFoundError: kotlin/jvm/internal/Intrinsics
	at com.zoftino.kotlin.hello.HellomainKt.main(hellomain.kt)
Caused by: java.lang.ClassNotFoundException: kotlin.jvm.internal.Intrinsics

The error occurs due to missing dependencies in the jar. To fix this, we need to create self contained jar which contains code from the jar project and includes all dependencies including kotlin related jars.

To create self contained jar, we need to use maven-assembly-plugin by adding below build entry to the pom xml.

<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>

Then run the maven build. In addition to simple jar, it will create jar with dependencies. Now change the external tools configuration to point to the jar which contains dependencies and run the jar. Here is the output of our kotlin self contained jar.

name: 
KOTLIN
Hello kotlin

Here is the pom xml for reference.

<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>

	<groupId>com.zoftino.kotlin</groupId>
	<artifactId>hello</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>jar</packaging>

	<name>hello</name>
	<url>http://maven.apache.org</url>

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<kotlin.version>1.2.51</kotlin.version>
		<main.class>com.zoftino.kotlin.hello.HellomainKt</main.class>
	</properties>

	<dependencies>
		<dependency>
			<groupId>org.jetbrains.kotlin</groupId>
			<artifactId>kotlin-stdlib</artifactId>
			<version>${kotlin.version}</version>
		</dependency>
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>3.8.1</version>
			<scope>test</scope>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<artifactId>kotlin-maven-plugin</artifactId>
				<groupId>org.jetbrains.kotlin</groupId>
				<version>${kotlin.version}</version>
				<executions>
					<execution>
						<id>compile</id>
						<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>
					<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>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-jar-plugin</artifactId>
				<version>2.6</version>
				<configuration>
					<archive>
						<manifest>
							<addClasspath>true</addClasspath>
							<mainClass>${main.class}</mainClass>
						</manifest>
					</archive>
				</configuration>
			</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>