Gradleビルドの設定

Estimated reading time: 4 minutes

このガイドではbuild.gradleファイルの作成方法とKtorをサポートするための設定方法について説明します。

目次:

基本的なKotlinのbuild.gradleファイル(Ktor設定無し)

まず初めに、Kotlinを含むスケルトンのbuild.gradleファイルが必要です。 任意のテキストエディタで作成できますし、IntelliJを使う場合はIntelliJ guideの方法で作成できます。

最初のファイルは以下のような見た目になります:

build.gradle
group 'Example'
version '1.0-SNAPSHOT'

buildscript {
    ext.kotlin_version = '1.3.70'

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

Ktorへの依存の追加とビルド設定

Ktorのアーティファクトはbintrayのレポジトリに配置されています。 そしてそのコアの部分はkotlinx.coroutinesライブラリに依存しており、それはjcenterリポジトリ内にあります。

そのため両方のリポジトリをbuild.gradleファイルのrepositoriesブロックに追加する必要があります:

jcenter()

Ktorのアーティファクトの参照ごとにバージョンを指定する必要があります。 重複を避けるため、buildscriptブロック内のextraプロパティ(またはgradle.propertiesファイル内)にバージョンを指定するとそれを後で使うことができます。

ext.ktor_version = '1.3.2'

ktor-server-coreを設定したバージョンktor_versionで追加する必要があります。

compile "io.ktor:ktor-server-core:$ktor_version"

groovyにおいては、シングルクオートの文字列とダブルクオートの文字列があり、 ダブルクオートの文字列においては上のバージョン値のような変数の展開ができます。 そのためダブルクオートの文字列を使う必要があります。

KotlinコンパイラーにJava8互換のバイトコードの生成をすることを伝える必要があります。

compileKotlin {
    kotlinOptions.jvmTarget = "1.8"
}
compileTestKotlin {
    kotlinOptions.jvmTarget = "1.8"
}

エンジンの選択と設定

Ktorは様々な環境で動作します。 例えばNetty、Jetty、その他Servlet互換のアプリケーションコンテナ(例:Tomcat)などです。

以下の例はNettyベースでKtorを設定する方法です。 その他のエンジンについてはアーティファクトをご覧ください。

ktor-server-nettyへの依存を追加し、前に定義したktor_versionプロパティを指定します。 このモジュールはNettyによるWebサーバと、その上でKtorが動く上で必要なコードを提供します。

compile "io.ktor:ktor-server-netty:$ktor_version"

最終的なbuild.gradleファイル(Ktor設定有り)

設定が完了すれば、build.gradleファイルは以下のようになっているかと思います:

build.gradle
group 'Example'
version '1.0-SNAPSHOT'

buildscript {
    ext.kotlin_version = '1.3.70'
    ext.ktor_version = '1.3.2'

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

Gradleを起動することで依存の解決と設定の妥当性検証を行うことができます。(起動はgradleコマンドか、gradle wrapperを利用する場合は./gradlew

以下のチュートリアルでは最も基本的な設定から、アプリケーション開発を始める際に使える機能を盛り込んだ設定までお見せします。

IntelliJ: 事前要件

  1. 最新バージョンのIntelliJ IDEAがインストールされていること
  2. Kotlinプラグイン、Gradleプラグインが有効になっていること(デフォルトでは有効です)

IntelliJ IDEAのメインメニューで以下の場所からチェックできます。

  • Windows: File -> Settings -> Plugins
  • Mac: IntelliJ IDEA -> Settings -> Plugins

IntelliJ: プロジェクトの開始

  1. File -> New -> Project:

    Ktor IntelliJ: File New Project

  2. Gradleを選択し、Additional Libraries and Frameworksの下にあるJavaKotlin (Java)をチェックします。プロジェクトのSDKを確認しNextをクリックします:

    Ktor IntelliJ: Gradle Kotlin JVM

  3. GroupIdを入れます: Example ArtifactIdを入れます: Example Nextをクリックします:

    Ktor IntelliJ: GroupId

  4. Project名を入れます: Example Projectのファイルパスを指定します: a/path/on/your/filesystem Finishをクリックします:

    Ktor IntelliJ: Project Location Name

  5. Gradleが動き出すまで数秒待ちます。そうすると以下のようにプロジェクト構造が見れるようになります。:

    Ktor IntelliJ: Project Structure

  6. build.gradleファイルのアーティファクトやリポジトリ設定を更新します:

    • compile("io.ktor:ktor-server-netty:$ktor_version")build.gradledependenciesブロックに追加
    • jcenter()repositoriesブロックに追加

    Ktor IntelliJ: Build Gradle

build.gradleの設定に関する詳細な説明はGradleビルドの設定をご覧ください。

Auto Importオプションを設定したい場合、右下のほうにAuto Importの設定を設定を促す通知が出てくるのでクリックすることで設定を行うことができます。

IntelliJ: Gradleのセットアップ

このセクションはGradleについての基本的な知識を持っている人を想定しています。 Gradleをもし使ったことがなければ、gradle.orgがGradleを始める上で有効ないくつかのガイドを提供してくれています。

単純なKtorアプリケーションを以下のようにしてセットアップすることができます。

Ktor Build with Gradle

Text version:

Groovy
// build.gradle

group 'Example'
version '1.0-SNAPSHOT'

buildscript {
    ext.kotlin_version = '1.3.70'
    ext.ktor_version = '1.3.2'

    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.2"

plugins {
    application
    kotlin("jvm") version "1.3.70"
}

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

もちろん、実際のアーティファクトを含めることも忘れてはいけません。 Quickstartのページでは、ktor-server-nettyを使いました。 そのアーティファクトはKtorのコア部分、Netty、KtorとNettyとのコネクタを推移的依存として含んでいます。 もちろんその他の依存を好きに追加することができます。

Ktorはモジュール化した設計になっているため、追加で他のリポジトリにあるアーティファクトから特定の機能を追加することもできます。 必要なアーティファクト(およびそれを配布するリポジトリ)を機能ごとに探す必要があります。

IntelliJ: アプリケーションの作成

src/main/kotlinディレクトリを選択し、新しいパッケージを作成します。 新しいパッケージ名はblogにします。

ディレクトリを選択し、その下にBlogAppという名前で新しいファイルを作成します。

Ktor IntelliJ: Create Kotlin File

Ktor IntelliJ: Create Kotlin File Name

以下のコードをコピーアンドペーストします。

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

Ktor IntelliJ: Program

これで’blog.BlogAppKt‘を起動できるようになりました。 🐞がついているアイコンを押し、Debug 'blog.BlogAppKt'を選択します。

Ktor IntelliJ: Program Run

これによってIntelliJの右上部に起動設定も作成され、再度同じ設定で簡単に実行できるようになります。

Ktor IntelliJ: Program Run Config

これによりNettyによるWebサーバが起動します。 ブラウザでURLlocalhost:8080を入力することでブログサンプルページを見ることができるようになります。

Ktor IntelliJ: Website

IntelliJ: Application objectを使うことで改善

上で行った設定はたくさんのネストブロックが発生するため、アプリケーションに機能を追加していく上では理想的でないです。 そこでApplication objectを使いそれをmain関数内のembeddedServerから参照することで、その点を改善することができます。

BlogApp.kt内のコードを以下のように変更し試してみてください:

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: 設定データの切り出し

上のコードではmain関数のembeddedServer内でアプリケーション設定を行うようになっていますが、 別の設定ファイルに切り出すことで将来的なデプロイや変更に対しより柔軟性をもたせることができるようになります。 src/main/resourcesディレクトリ内において、application.confという名前で以下の内容のテキストファイルを新規作成します:

application.conf
ktor {
    deployment {
        port = 8080
    }

    application {
        modules = [ blog.BlogAppKt.main ]
    }
}

その後BlogApp.ktからmain関数を削除し、fun Application.module()fun Application.main()に変更します。 しかし、今アプリケーションを起動しても、”Top-level function ‘main’ not found in package blog.” というエラーメッセージとともに失敗します。 Application.main()関数は今拡張関数でありトップレベルのmain関数として認識できないからです。

IntelliJ IDEAは自動的に認識はできないので、新しいmainクラスを指定してやる必要があります。 build.gradleに以下のように追加します:

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

その後Run -> Edit Configurationsを開き、blog.BlogAppKtの設定を選択し、mainクラスをio.ktor.server.netty.EngineMainに変更します。

新しい設定で起動すると、アプリケーションが再び起動できるようになります。

ログ設定

アプリケーションイベントやその他有益な情報をログ出力したい場合は、ロギングページをご覧ください。