Kotlin for Server-Side
ServerSideの現状を以下に軽くまとめてみました。
Frameworks for Server-side Development with Kotlin
-
Spring
- Javaでの有名なWebアプリケーションFramework
-
Vert.x
- JVM上でReactiveアプリケーションを作成する為のToolkit
-
Ktor
- JetBrains社が作成しているWebアプリケーションFramework
-
kotlinx.html
- Kotlin DSL for HTML
今回は上記の中でも Ktor を試して見たいと思います。
環境構築
Ktor Project Generator で空のプロジェクトを作成し、ダウンロードします。
何も変更しない状態で「Build」を選択しプロジェクトをダウンロードします。
ダウンロードしたプロジェクトのディレクトリ構成は以下の様になってました。
.
├── build.gradle
├── gradle
│ └── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradle.properties
├── gradlew
├── gradlew.bat
├── resources
│ ├── application.conf
│ └── logback.xml
├── settings.gradle
└── src
└── Application.kt
※ ダウンロードしたプロジェクトのGradleのVerが 4.10
となっており、後述する Gradle Shadow を使用する際に
Versionが古いと怒られるので gradle-wrapper.properties
のgradleのversionを 5.6.4
に変更してます。
また、build.gradle
とApplication.kt
は以下の様になってました。
buildscript {
repositories {
jcenter()
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
apply plugin: 'kotlin'
apply plugin: 'application'
group 'com.example'
version '0.0.1-SNAPSHOT'
mainClassName = "io.ktor.server.netty.EngineMain"
sourceSets {
main.kotlin.srcDirs = main.java.srcDirs = ['src']
test.kotlin.srcDirs = test.java.srcDirs = ['test']
main.resources.srcDirs = ['resources']
test.resources.srcDirs = ['testresources']
}
repositories {
mavenLocal()
jcenter()
}
dependencies {
compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
compile "io.ktor:ktor-server-netty:$ktor_version"
compile "ch.qos.logback:logback-classic:$logback_version"
testCompile "io.ktor:ktor-server-tests:$ktor_version"
}
package com.example
import io.ktor.application.*
import io.ktor.response.*
import io.ktor.request.*
fun main(args: Array<String>): Unit = io.ktor.server.netty.EngineMain.main(args)
@Suppress("unused") // Referenced in application.conf
@kotlin.jvm.JvmOverloads
fun Application.module(testing: Boolean = false) {
}
Dockerで起動できる様にする
こちらを参考に環境構築を行います。
Gradle Shadow
Jarを生成してくれる、GradleのPlugin。これを使ってjarを生成しDocker内で起動します。
build.gradle
を以下に修正
buildscript {
repositories {
jcenter()
maven {
url 'https://plugins.gradle.org/m2/'
}
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath "com.github.jengelman.gradle.plugins:shadow:5.2.0"
}
}
apply plugin: 'kotlin'
apply plugin: 'application'
apply plugin: 'com.github.johnrengelman.shadow'
group 'com.example'
version '0.0.1-SNAPSHOT'
mainClassName = "io.ktor.server.netty.EngineMain"
sourceSets {
main.kotlin.srcDirs = main.java.srcDirs = ['src']
test.kotlin.srcDirs = test.java.srcDirs = ['test']
main.resources.srcDirs = ['resources']
test.resources.srcDirs = ['testresources']
}
repositories {
mavenLocal()
jcenter()
maven { url "https://dl.bintray.com/kotlin/ktor" }
}
dependencies {
compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
compile "io.ktor:ktor-server-netty:$ktor_version"
compile "ch.qos.logback:logback-classic:$logback_version"
testCompile "io.ktor:ktor-server-tests:$ktor_version"
}
shadowJar {
baseName = 'my-application'
classifier = null
version = null
}
以下のDockerfileをプロジェクト直下に追加
FROM openjdk:8-jdk
RUN mkdir /app
WORKDIR /app
ADD . $WORKDIR
RUN ./gradlew wrapper # gradle wrapper関連を諸々アップデート
起動時にkickするshellを作成 bin/start_server.sh
#!/bin/bash
set -e
source ~/.bashrc
./gradlew build
cp ./build/libs/my-application.jar .
java -server -XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap -XX:InitialRAMFraction=2 -XX:MinRAMFraction=2 -XX:MaxRAMFraction=2 -XX:+UseG1GC -XX:MaxGCPauseMillis=100 -XX:+UseStringDeduplication -jar my-application.jar
docker-compose.yml
を以下の内容で作成する。
version: '3'
services:
app:
build:
context: .
dockerfile: ./Dockerfile
ports:
- '8080:8080'
volumes:
- .:/app
command:
bin/start_server.sh
あとは docker-compose up
で起動し、http://0.0.0.0:8080
にアクセスできればOKです。
作成したプロジェクトはこちらにアップしてます。
バッドノウハウ
* What went wrong:
A problem occurred evaluating root project 'ktor-demo'.
> Failed to apply plugin [class 'com.github.jengelman.gradle.plugins.shadow.ShadowBasePlugin']
> This version of Shadow supports Gradle 5.0+ only. Please upgrade.
gradleのバージョンが古い。こちらを参考に、
gradle/wrapper/gradle-wrapper.properties
のversionを変更し、./gradlew wrapper
を実行する
gradleのversionはこちらで確認できる。
* What went wrong:
Execution failed for task ':compileKotlin'.
> Kotlin could not find the required JDK tools in the Java installation '/usr/lib/jvm/java-1.8-openjdk/jre' used by Gradle. Make sure Gradle is running on a JDK, not JRE.
エラーメッセージの通りで、JREではなくJDKを指定する。
参考のリポジトリのDockerfileが ROM openjdk:8-jre-alpine
になっている為、openjdk:8-jdk
に修正する。