- Setting up a Gradle Build
- Basic Kotlin build.gradle file (without Ktor)
- Add Ktor dependencies and configure build settings
- Choose your engine and configure it
- Final build.gradle (with Ktor)
- IntelliJ: Prerequisites
- IntelliJ: Start a Project
- IntelliJ: Gradle Setup
- IntelliJ: Create the App
- IntelliJ: Improve the app with the Application object
- IntelliJ: Extract out Configuration Data
- Configure logging
Setting up a Gradle Build
In this guide, we will show you how to create a build.gradle
fileand how to configure it to support Ktor.
Table of contents:
- Basic Kotlin
build.gradle
file (without Ktor) - Add Ktor dependencies and configure build settings
- Choose your engine and configure it
- Final
build.gradle
(with Ktor) - IntelliJ: Prerequisites
- IntelliJ: Start a Project
- IntelliJ: Gradle Setup
- IntelliJ: Create the App
- IntelliJ: Improve the app with the Application object
- IntelliJ: Extract out Configuration Data
- Configure logging
Basic Kotlin build.gradle file (without Ktor)
First of all, you need a skeleton build.gradle
file including Kotlin.You can create it with any text editor, or you can use IntelliJ to createit following the IntelliJ guide.
The initial file looks like this:
build.gradle
group 'Example'
version '1.0-SNAPSHOT'
buildscript {
ext.kotlin_version = '1.3.61'
repositories {
mavenCentral()
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
apply plugin: 'java'
apply plugin: 'kotlin'
sourceCompatibility = 1.8
repositories {
jcenter()
}
dependencies {
compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
testCompile group: 'junit', name: 'junit', version: '4.12'
}
Add Ktor dependencies and configure build settings
Ktor artifacts are located in a specific repository on bintray.And its core has dependencies on the kotlinx.coroutines
library thatcan be found on jcenter
.
You have to add both to the repositories
block in the build.gradle
file:
jcenter()
You have to specify that version in each Ktor artifact reference,and to avoid repetitions, you can specify that version in an extra propertyin the buildscript
block (or in a gradle.properties
file) for using it later:
ext.ktor_version = '1.3.0'
Now you have to add the ktor-server-core
artifact, referencing the ktor_version
you specified:
compile "io.ktor:ktor-server-core:$ktor_version"
In groovy, there are single-quoted strings (instead of characters)and double-quoted strings, to be able to interpolate variables likeversions, you have to use double-quoted strings.
You need to tell the Kotlin compiler to generate bytecode compatible with Java 8:
compileKotlin {
kotlinOptions.jvmTarget = "1.8"
}
compileTestKotlin {
kotlinOptions.jvmTarget = "1.8"
}
Choose your engine and configure it
Ktor can run in many environments, such as Netty, Jetty or any otherServlet-compatible Application Container such as Tomcat.
This example shows you how to configure Ktor with Netty.For other engines see artifacts for a list ofavailable artifacts.
You will add a dependency for ktor-server-netty
using thektor_version
property you have created. This module providesa Netty web server and all the required code to run Ktorapplication on top of it:
compile "io.ktor:ktor-server-netty:$ktor_version"
Final build.gradle (with Ktor)
When you are done, the build.gradle
file should look like this:
build.gradle
group 'Example'
version '1.0-SNAPSHOT'
buildscript {
ext.kotlin_version = '1.3.61'
ext.ktor_version = '1.3.0'
repositories {
mavenCentral()
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
apply plugin: 'java'
apply plugin: 'kotlin'
sourceCompatibility = 1.8
compileKotlin {
kotlinOptions.jvmTarget = "1.8"
}
compileTestKotlin {
kotlinOptions.jvmTarget = "1.8"
}
kotlin {
experimental {
coroutines "enable"
}
}
repositories {
jcenter()
}
dependencies {
compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
compile "io.ktor:ktor-server-netty:$ktor_version"
testCompile group: 'junit', name: 'junit', version: '4.12'
}
You can now run Gradle (just gradle
or ./gradlew
if using the wrapper)to fetch dependencies and verify everything is set up correctly.
This tutorial will guide you from the most basic setup through to a fullfeatured setup you can use to start developing your app.
IntelliJ: Prerequisites
- The most recent version of IntelliJ IDEA
- Kotlin and Gradle plugins enabled (They should be enabled by default.) You can check this in IntelliJ IDEA in the main menu:
- Windows:
File -> Settings -> Plugins
- Mac:
IntelliJ IDEA -> Settings -> Plugins
IntelliJ: Start a Project
File -> New -> Project
:
- Select Gradle and under Additional Libraries and Frameworks, check Java and Kotlin (Java). Confirm that Project SDK is completed and click
Next
:
- Enter a GroupId:
Example
and ArtifactId:Example
and click Next:
- Complete Project name:
Example
and Project location:a/path/on/your/filesystem
and clickFinish
:
- Wait a few seconds for Gradle to run, and you should see a project structure like the following (with a few other files and directories):
Update your
build.gradle
file with the artifact and repositories for the classes to be available:- Include
compile("io.ktor:ktor-server-netty:$ktor_version")
, in yourbuild.gradle
’sdependencies
block - Include
jcenter()
in yourrepositories
block
- Include
For a more detailed guide on setting up the build.gradle
file, check the Getting Started with Gradle section.
When auto-import options, shows up (likely on bottom right hand side) click allow auto-import.
IntelliJ: Gradle Setup
This section assumes you have some basic knowledge of Gradle. If you have never used Gradle,gradle.org provides several guides to help you get started.
You can set-up a simple Ktor application using Gradle like this:
Text version:
Groovy
// build.gradle
group 'Example'
version '1.0-SNAPSHOT'
buildscript {
ext.kotlin_version = '1.3.61'
ext.ktor_version = '1.3.0'
repositories {
mavenCentral()
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
apply plugin: 'java'
apply plugin: 'kotlin'
apply plugin: 'application'
mainClassName = 'MainKt'
sourceCompatibility = 1.8
compileKotlin { kotlinOptions.jvmTarget = "1.8" }
compileTestKotlin { kotlinOptions.jvmTarget = "1.8" }
repositories {
mavenCentral()
}
dependencies {
compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
compile "io.ktor:ktor-server-netty:$ktor_version"
compile "ch.qos.logback:logback-classic:1.2.3"
testCompile group: 'junit', name: 'junit', version: '4.12'
}
Kotlin
// build.gradle.kts
import org.jetbrains.kotlin.gradle.dsl.Coroutines
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
group = "Example"
version = "1.0-SNAPSHOT"
val ktor_version = "1.3.0"
plugins {
application
kotlin("jvm") version "1.3.61"
}
repositories {
mavenCentral()
}
java {
sourceCompatibility = JavaVersion.VERSION_1_8
}
tasks.withType<KotlinCompile>().all {
kotlinOptions.jvmTarget = "1.8"
}
application {
mainClassName = "MainKt"
}
dependencies {
compile(kotlin("stdlib-jdk8"))
compile("io.ktor:ktor-server-netty:$ktor_version")
compile("ch.qos.logback:logback-classic:1.2.3")
testCompile(group = "junit", name = "junit", version = "4.12")
}
Since Ktor is not yet 1.0, we have custom Maven repositories for distributing our early preview artifacts.You have to set up a couple of repositories as shown below, so your tools can find Ktor artifacts and dependencies.
Of course, don’t forget to include the actual artifact! For our quickstart, we are using the ktor-server-netty
artifact.That includes Ktor’s core, netty, and the ktor-netty connector as transitive dependencies.You can, of course, include any additional dependencies that you need.
Since Ktor is designed to be modular, you will require additional artifacts and potentially other repositoriesfor specific features. You can find the required artifacts (and repositories where required) for each feature in thespecific feature documentation.
IntelliJ: Create the App
Select the src/main/kotlin
directory and create a new package. We will call it blog
.
Select that directory and create a new kotlin file under it named BlogApp
Copy and paste in the most basic setup for an app so that it looks like:
BlogApp.kt
package blog
import io.ktor.application.*
import io.ktor.http.*
import io.ktor.response.*
import io.ktor.routing.*
import io.ktor.server.engine.*
import io.ktor.server.netty.*
fun main(args: Array<String>) {
embeddedServer(Netty, 8080) {
routing {
get("/") {
call.respondText("My Example Blog", ContentType.Text.Html)
}
}
}.start(wait = true)
}
Now you can Run ‘blog.BlogAppKt
’. You can do it, by pressing the glutter icon with the 🐞 symbol and selecting Debug 'blog.BlogAppKt'
:
This will also create a run configuration in the upper-right part of IntelliJ, that will allow runningthis configuration again easily:
This will start the Netty web server.In your browser enter the URL: localhost:8080And you should see your example blog page.
IntelliJ: Improve the app with the Application object
The setup above has a lot of nested blocks and is not ideal for starting to add functionality to your app. We can improve it by using the Application object and referring to that from an embeddedServer call in the main function.
Change your code in BlogApp.kt to the following to try this:
BlogApp.kt
package blog
import io.ktor.application.*
import io.ktor.features.*
import io.ktor.http.*
import io.ktor.response.*
import io.ktor.routing.*
import io.ktor.server.engine.*
import io.ktor.server.netty.*
fun Application.module() {
install(DefaultHeaders)
install(CallLogging)
install(Routing) {
get("/") {
call.respondText("My Example Blog2", ContentType.Text.Html)
}
}
}
fun main(args: Array<String>) {
embeddedServer(Netty, 8080, watchPaths = listOf("BlogAppKt"), module = Application::module).start()
}
IntelliJ: Extract out Configuration Data
Although we can designate some application configuration data in the main function embeddedServer call, we can provide more flexibility for future deployments and changes by extracting this out to a separate configuration file. In the src/main/resources
directory we will create a new text file named application.conf
with the following content:
application.conf
ktor {
deployment {
port = 8080
}
application {
modules = [ blog.BlogAppKt.main ]
}
}
Then we delete the main function from BlogApp.kt
and change fun Application.module()
to fun Application.main()
. However, if we run the application now, it will fail with an error message like “Top-level function ‘main’ not found in package blog.” Our Application.main()
function is now a function extension and does not qualify as a top-level main function.
This requires us to indicate a new main class as IntelliJ IDEA will no longer be able to find it automatically. In build.gradle
we add:
Groovy
// build.gradle
apply plugin: 'application'
//mainClassName = 'io.ktor.server.netty.DevelopmentEngine' // For versions < 1.0.0-beta-3
mainClassName = 'io.ktor.server.netty.EngineMain' // Starting with 1.0.0-beta-3
Kotlin
// build.gradle.kts
plugins {
application
// ...
}
application {
mainClassName = "io.ktor.server.netty.EngineMain"
}
And then go to Run -> Edit Configurations
select the blog.BlogAppKt
configuration and change its Main class to:io.ktor.server.netty.EngineMain
Now when we run the new configuration, the application will start again.
Configure logging
If you want to log application events and useful information,you can read about it further in the logging page.