Setting up Project in IntelliJ IDEA (Gradle)

Estimated reading time: 4 minutes

This tutorial will guide you from the most basic setup through to a full featured setup you can use to start developing your app.

Table of contents:

Prerequisites

  1. The most recent version of IntelliJ IDEA
  2. 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

Start a Project

  1. File -> New -> Project:

    Ktor IntelliJ: File New Project

  2. Select Gradle and under Additional Libraries and Frameworks, check Java and Kotlin (Java). Confirm that Project SDK is completed and click Next:

    Ktor IntelliJ: Gradle Kotlin JVM

  3. Enter a GroupId: Example and ArtifactId: Example and click Next:

    Ktor IntelliJ: GroupId

  4. Check the checkboxes for Use auto-import and Create separate module per source set. Confirm the Use default gradle wrapper radio button is selected and that Gradle JVM is populated and click Next:

    Ktor IntelliJ: Gradle Config

  5. Complete Project name: Example and Project location: a/path/on/your/filesystem and click Finish:

    Ktor IntelliJ: Project Location Name

  6. 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):

    Ktor IntelliJ: Project Structure

  7. 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 your build.gradle’s dependencies block
    • Include maven { url "http://kotlin.bintray.com/ktor" } and jcenter() in your repositories block

    Ktor IntelliJ: Build Gradle

For a more detailed guide on setting up the build.gradle file, check the Getting Started with Gradle section.

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

Ktor IntelliJ: Create Kotlin File

Ktor IntelliJ: Create Kotlin File Name

Copy and paste in the most basic setup for an app so that it looks like:

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

Ktor IntelliJ: Program

Now you can Run ‘blog.BlogAppKt’. You can do it, by pressing the glutter icon with the 🐞 symbol and selecting Debug 'blog.BlogAppKt':

Ktor IntelliJ: Program Run

This will also create a run configuration in the upper-right part of IntelliJ, that will allow running this configuration again easily:

Ktor IntelliJ: Program Run Config

This will start the Netty web server. In your browser enter the URL: localhost:8080 And you should see your example blog page.

Ktor IntelliJ: Website

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:

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()
}

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:

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:

apply plugin: 'application'

mainClassName = 'io.ktor.server.netty.DevelopmentEngine'

And then go to Run -> Edit Configurations select the blog.BlogAppKt configuration and change its Main class to: io.ktor.server.netty.DevelopmentEngine

Now when we run the new configuration, the application will start again.