Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Free Learning
Arrow right icon
Arrow up icon
GO TO TOP
Kotlin Programming Cookbook

You're reading from   Kotlin Programming Cookbook Explore more than 100 recipes that show how to build robust mobile and web applications with Kotlin, Spring Boot, and Android

Arrow left icon
Product type Paperback
Published in Jan 2018
Publisher
ISBN-13 9781788472142
Length 434 pages
Edition 1st Edition
Languages
Tools
Arrow right icon
Authors (2):
Arrow left icon
Aanand Shekhar Roy Aanand Shekhar Roy
Author Profile Icon Aanand Shekhar Roy
Aanand Shekhar Roy
Rashi Karanpuria Rashi Karanpuria
Author Profile Icon Rashi Karanpuria
Rashi Karanpuria
Arrow right icon
View More author details
Toc

Table of Contents (16) Chapters Close

Preface 1. Installation and Working with Environment FREE CHAPTER 2. Control Flow 3. Classes and Objects 4. Functions 5. Object-Oriented Programming 6. Collections Framework 7. Handling File Operations in Kotlin 8. Anko Commons and Extension Function 9. Anko Layouts 10. Databases and Dependency Injection 11. Networking and Concurrency 12. Lambdas and Delegates 13. Testing 14. Web Services with Kotlin 15. Other Books You May Enjoy

How to build a self-executable JAR with Gradle and Kotlin

Kotlin is great for creating small command-line utilities, which can be packaged and distributed as normal JAR files. In this recipe, we will see how to do it using Gradle build system. Gradle build system is one of the most sophisticated build systems out there. It is the default build tool for Android and is designed to ease scripting of complex, multilanguage builds with a lot of dependencies (typical of big projects). It achieves the goal of automating your project without compromising on maintainability, usability, flexibility, extensibility, or performance. We will be using Gradle build system to create a self-extracting JAR file. This JAR file can be distributed to and run on any platform supporting Java.

Getting ready

You need an IDE (preferably IntelliJ or Android Studio), and you need to tell it where your Kotlin files are present. You can do so by specifying it in the build.gradle file by adding the following:

sourceSets {
main.java.srcDirs += 'src/main/kotlin/'
}

The preceding lines are required if you have your Kotlin files separated from Java packages. This is optional, and you can continue working with Kotlin files under Java packages, but it’s a good practice to keep them separated.

We’ll be creating a very simple function that just prints Hello World! when executed. Since it’ll be a simple function, I am just adding it as a top-level main() function.

How to do it...

Let's go through these steps, with which we can create a self-executable JAR:

  1. We’ll create a simple class HelloWorld.kt having the main function, which just prints out “Hello world!”:
fun main(args:Array<String>){
println("Hello world")
}
  1. Now we need to configure a jar task, which Gradle build goes through to inform it of our entry to our project. In a Java project, this will be the path to the class where our main() function resides, so you will need to add this jar task in build.gradle:
jar {
manifest {
attributes 'Main-Class': 'HelloWorldKt'
}
from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
}
  1. After adding the preceding snippet to build.gradle, you need to run the following gradle command to create the jar file:
./gradlew clean jar
  1. The created jar file can be found in the build/libs folder. Now you can just run the java -jar demo.jar command to run the JAR file.

After you do that, you can see the output in the console:

How it works...

To make self-executable JARs, we need a manifest file called MANIFEST.MF in the META-INF directory. For our purposes here, we just need to specify the name of the Java class that contains the Java-based extractor program's main() method.

One might argue that even though we don’t have top-level class declaration, we are specifying it as HelloWorldKt in the code for the jar task:

manifest {
attributes 'Main-Class': 'HelloWorldKt'
}

The reason for putting the preceding code block in the jar task is that Kotlin compiler adds all top-level functions to respective classes for back-compatibility with JVM. So, the class generated by Kotlin compiler will have the filename, plus the Kt suffix, which makes it HelloWorldKt.

Also, the reason we added from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } } in jar task is because we want Gradle to copy all of a JAR’s dependencies. The reason for doing so is that, by default, when Gradle (as well as Maven) packs some Java class files into a JAR file, it assumes that this JAR file will be referenced by an application, where all of its dependencies are also accessible in the classpath of the loading application. So, by specifying the preceding lines in jar task, we are telling gradle to take all of this JAR’s referenced dependencies and copy them as part of the JAR itself. In the Java community, this is known as a fat JAR. In a fat JAR, all the dependencies end up within the classpath of the loading application, so the code can be executed without problems. The only downside to creating fat JARs is their growing file size (which kind of explains the name), though it is not a big concern in most situations.

You have been reading a chapter from
Kotlin Programming Cookbook
Published in: Jan 2018
Publisher:
ISBN-13: 9781788472142
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at $19.99/month. Cancel anytime
Banner background image