Giter Club home page Giter Club logo

ktor's Introduction

Ktor logo

Official JetBrains project Maven Central Kotlin Slack channel GitHub License Contribute with Gitpod

Ktor is an asynchronous framework for creating microservices, web applications and more. Written in Kotlin from the ground up.

First add the dependency to your project:

repositories {
    mavenCentral()
}

dependencies {
    implementation("io.ktor:ktor-server-netty:$ktor_version")
}

Then create an Application and install some features:

import io.ktor.server.netty.*
import io.ktor.server.routing.*
import io.ktor.server.application.*
import io.ktor.http.*
import io.ktor.server.response.*
import io.ktor.server.engine.*

fun main(args: Array<String>) {
    embeddedServer(Netty, 8080) {
        routing {
            get("/") {
                call.respondText("Hello, world!", ContentType.Text.Html)
            }
        }
    }.start(wait = true)
}

You also can use Ktor Gradle Plugin to configure bom, run tasks and deployment:

plugins {
    id("io.ktor.plugin") version "2.3.4"
}

dependencies {
    implementation("io.ktor:ktor-server-netty")
}

To run the created application, execute:

./gradlew run
  • Runs embedded web server on localhost:8080
  • Installs routing and responds with Hello, world! when receiving a GET http request for the root path

Start using Ktor

Build your first Kotlin HTTP or RESTful application using Ktor: start.ktor.io

Principles

Unopinionated

Ktor Framework doesn't impose a lot of constraints on what technology a project is going to use – logging, templating, messaging, persistence, serialization, dependency injection, etc. Sometimes it may be required to implement a simple interface, but usually it is a matter of writing a transforming or intercepting function. Features are installed into the application using a unified interception mechanism which allows building arbitrary pipelines.

Ktor Applications can be hosted in any servlet container with Servlet 3.0+ API support such as Tomcat, or standalone using Netty or Jetty. Support for other hosts can be added through the unified hosting API.

Ktor APIs are mostly functions calls with lambdas. Thanks to Kotlin DSL capabilities, the code looks declarative. Application composition is entirely up to the developer's choice – with functions or classes, using dependency injection framework or doing it all manually in the main function.

Asynchronous

The Ktor pipeline machinery and API are utilising Kotlin coroutines to provide easy-to-use asynchronous programming model without making it too cumbersome. All host implementations are using asynchronous I/O facilities to avoid thread blocking.

Testable

Ktor applications can be hosted in a special test environment, which emulates a web server to some extent without actually doing any networking. It provides easy way to test an application without mocking too much stuff, and still achieve good performance while validating application calls. Running integration tests with a real embedded web server are of course possible, too.

JetBrains Product

Ktor is an official JetBrains product and is primarily developed by the team at JetBrains, with contributions from the community.

Documentation

Please visit ktor.io for Quick Start and detailed explanations of features, usage and machinery.

  • Getting started with Gradle
  • Getting started with Maven
  • Getting started with IDEA

Reporting Issues / Support

Please use our issue tracker for filing feature requests and bugs. If you'd like to ask a question, we recommend StackOverflow where members of the team monitor frequently.

There is also community support on the Kotlin Slack Ktor channel

Reporting Security Vulnerabilities

If you find a security vulnerability in Ktor, we kindly request that you reach out to the JetBrains security team via our responsible disclosure process.

Inspirations

Kotlin web frameworks such as Wasabi and Kara, which are currently deprecated.

Contributing

Please see the contribution guide and the Code of conduct before contributing.

ktor's People

Contributors

andreyaksenov avatar bjhham avatar camdenorrb avatar cy6ergn0m avatar dependabot[bot] avatar dmitrievanthony avatar dragneelfps avatar e5l avatar elizarov avatar hfhbd avatar hhariri avatar jeiea avatar jlleitschuh avatar lolilofit avatar marychatte avatar ololoshechkin avatar orangy avatar pecanw avatar qwwdfsad avatar renovate[bot] avatar rsinukov avatar sommd avatar soywiz avatar spand avatar stexxe avatar t-fowl avatar thomas-vos avatar thumannw avatar triplem avatar turansky avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ktor's Issues

Статические файлы, медленная работа

отдает статические файлы очень медленно, или происходит отваливание по таймауту.
Собирал из main и pipeline веток.
Проверяю на embedded jetty.
На windows 10 пару тройку файлов выдает с лагами, на Mac Os облом).

вариант вызова
server = embeddedJettyServer(9090) {
serveClasspathResources("/public")
}
и
server = embeddedJettyServer(9090) {
serveFileSystem(File(fullpath+"/build/resources/main/public"))
}

html-builder should log errors

The current implementation of html-builder uses an HTMLStreamBuilder to produce html through kotlinx.html library.

HTMLStreamBuilder is a TagConsumer that uses the default onTagError implementation : https://github.com/Kotlin/kotlinx.html/blob/master/shared/src/main/kotlin/api.kt#L14

In case of an exception in a bloc that produces html, nothing is logged and a empty html page is returned to the client.

To simplify debugging, in case of error or exception a trace should be logged.

StaticContent: handle empty {path...}

My error was to use /static/* as the route instead of /static. Because of this the path variable was empty and it crashed.
Maybe there should be a way to prevent this kind of user error. Documenting StaticContent would be a first step.

Also don't try to read the basePath folder as a file when path is empty.

Exception from FileReadChannel.

No quite sure why it happened but should be handled somehow.

java.lang.IllegalArgumentException: endInclusive shouldn't be less than start but start = 0, endInclusive = -1
    at org.jetbrains.ktor.nio.FileReadChannel.<init>(FileReadChannel.kt:16)
    at org.jetbrains.ktor.nio.FileReadChannel.<init>(FileReadChannel.kt:8)
    at org.jetbrains.ktor.nio.FileReadChannelKt.asyncReadOnlyFileChannel(FileReadChannel.kt:84)
    at org.jetbrains.ktor.nio.FileReadChannelKt.asyncReadOnlyFileChannel(FileReadChannel.kt:85)
    at org.jetbrains.ktor.nio.FileReadChannelKt.asyncReadOnlyFileChannel$default(FileReadChannel.kt:85)
    at org.jetbrains.ktor.content.LocalFileContent.channel(StaticContent.kt:31)
    at org.jetbrains.ktor.content.LocalFileContent.channel(StaticContent.kt:15)
    at org.jetbrains.ktor.content.FinalContent$ChannelContent.startContent(FinalContent.kt:28)
    at org.jetbrains.ktor.host.BaseApplicationCall$1.invoke(BaseApplicationCall.kt:64)
    at org.jetbrains.ktor.host.BaseApplicationCall$1.invoke(BaseApplicationCall.kt:11)
    at org.jetbrains.ktor.pipeline.PipelineBlock.call(PipelineBlock.kt:9)
    at org.jetbrains.ktor.pipeline.PipelineMachine.proceed(PipelineMachine.kt:34)
    at org.jetbrains.ktor.pipeline.PipelineExecution.proceed(PipelineExecution.kt:18)
    at org.jetbrains.ktor.pipeline.AsyncKt.continuePipeline(Async.kt:104)
    at org.jetbrains.ktor.transform.TransformationSupport$transform$1$1.invoke(TransformIntercept.kt:39)
    at org.jetbrains.ktor.transform.TransformationSupport$transform$1$1.invoke(TransformIntercept.kt:11)
    at org.jetbrains.ktor.pipeline.PipelineMachine.proceed(PipelineMachine.kt:86)
    at org.jetbrains.ktor.pipeline.PipelineMachine.execute(PipelineMachine.kt:15)
    at org.jetbrains.ktor.transform.TransformationSupport.transform(TransformIntercept.kt:48)
    at org.jetbrains.ktor.transform.TransformationSupport.access$transform(TransformIntercept.kt:11)
    at org.jetbrains.ktor.transform.TransformationSupport$install$1$1.invoke(TransformIntercept.kt:23)
    at org.jetbrains.ktor.transform.TransformationSupport$install$1$1.invoke(TransformIntercept.kt:11)
    at org.jetbrains.ktor.pipeline.PipelineBlock.call(PipelineBlock.kt:9)
    at org.jetbrains.ktor.pipeline.PipelineMachine.proceed(PipelineMachine.kt:34)
    at org.jetbrains.ktor.pipeline.PipelineMachine.execute(PipelineMachine.kt:15)
    at org.jetbrains.ktor.pipeline.AsyncKt$executeOn$1.run(Async.kt:23)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180)
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)

Exception in NettyApplicationRequest.close

2016-12-07 12:06:43.196 [nioEventLoopGroup-3-1] WARN  i.n.u.c.AbstractEventExecutor - A task raised an exception. Task: org.jetbrains.ktor.netty.NettyApplicationRequest$close$$inlined$executeInLoop$1@22adee83
java.util.NoSuchElementException: org.jetbrains.ktor.netty.BodyHandlerChannelAdapter
	at io.netty.channel.DefaultChannelPipeline.getContextOrDie(DefaultChannelPipeline.java:1089) ~[netty-transport-4.1.5.Final.jar:4.1.5.Final]
	at io.netty.channel.DefaultChannelPipeline.remove(DefaultChannelPipeline.java:428) ~[netty-transport-4.1.5.Final.jar:4.1.5.Final]
	at org.jetbrains.ktor.netty.NettyApplicationRequest$close$$inlined$executeInLoop$1.run(NettyApplicationRequest.kt:141) ~[classes/:na]
	at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:163) ~[netty-common-4.1.5.Final.jar:4.1.5.Final]
	at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:418) [netty-common-4.1.5.Final.jar:4.1.5.Final]
	at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:440) [netty-transport-4.1.5.Final.jar:4.1.5.Final]
	at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:873) [netty-common-4.1.5.Final.jar:4.1.5.Final]
	at io.netty.util.concurrent.DefaultThreadFactory$DefaultRunnableDecorator.run(DefaultThreadFactory.java:144) [netty-common-4.1.5.Final.jar:4.1.5.Final]
	at java.lang.Thread.run(Thread.java:745) [na:1.8.0_111]

Reproducible on Login in you-kube sample.

kweet partial migration?

From slack:
https://kotlinlang.slack.com/archives/ktor/p1484960403000468
Julio Cotta [11:00 PM]

class KweetApp : AutoCloseable ...

I understand why KweetApp is autocloseable... it wants to close the database pool when shutting down... I just dont understand is when ktor calls close()`... the only verification of AutoCloseable is here

fun <A : Pipeline<*>, F : Any> A.uninstallFeature(key: AttributeKey<F>) {
    val registry = attributes.getOrNull(ApplicationFeature.registry) ?: return
    val instance = registry.getOrNull(key) ?: return
    if (instance is AutoCloseable)
        instance.close()
    registry.remove(key)
}

As I understand... instance.close() is a feature... does KweetApp is seem as such?

Ilya Ryzhenkov [JB] [11:04 PM]
Yep, unfinished transformation from Application-as-a-feature to Application-as-a-function. Need to fix that. Could you please file an issue?

How to run missing in the docs

As a rookie I have no idea how to run the hello world sample from the command line. Can you maybe add that to the docs? I suppose its a simple command

application/json default charset is not UTF-8

RFC4627 Section 3 specifies that the default encoding of application/json is UTF-8. Ktor falls back to ISO-8859-1 (see RequestContent.kt:11).

Further, the application/json entry on IANA has the note:

Note:  No "charset" parameter is defined for this registration.
Adding one really has no effect on compliant recipients.

Ktor doesn't comply here to the standard and is to be considered as non-compliant server. See discussions on this issue e.g. on request/request#383.

Please fallback on application/json to UTF-8.

Basic authentication does not work on first attempt

When I have following code fragments:

fun main(args: Array<String>) {
    embeddedNettyServer(8080) {
        get("/test") {
            authentication {
                println("authentication...")
                basicAuthentication("ktor") {
                    println("within basic ...")
                    authenticate(it)
                }
            }
            call.respond("Hello")
        }
    }.start(wait = true)
}

fun authenticate(user: UserPasswordCredential): Principal? {
    println(user)
    return users[user.name]?.let {
        if (it == user.password)
            UserIdPrincipal(user.name)
        else null
    }
}

I can call curl abosch@localhost:8080/test and get "Hello" prompt on first call. Following calls show me correctly that no password is specified and "Hello" is not returned.

Is it a bug or do I not understand how to use the authentication :) ?

Httpbin sample

Hello,

I am implementing here a ktor version of https://httpbin.org/ HTTP Request & Response Service

It's nowhere done, but I wanted to know if there is some interest that I eventually contribute it as a ktor sample.

Jean-Michel

Threads stuck in infinite loop with bad input data

If an application/x-www-form-urlencoded POST contains invalid data like foo=foo+%+bar ktor will create threads stuck in an infinite loop at org.jetbrains.ktor.http.CodecsKt.decode(Codecs.kt:37).

Perhaps a fuzzer should be used in the test suite to ensure ktor is resilient to this sort of problem.

java.lang.IllegalStateException: ReadListener already set

I have a long running request (>1min). At some point the server just crashes with the following breakpoint.
Even if I just put a "thread only" suspending breakpoint in the post body it crashes

java.lang.IllegalStateException: ReadListener already set
    at org.eclipse.jetty.server.HttpInput.setReadListener(HttpInput.java:600) ~[jetty-server-9.3.13.v20161014.jar:9.3.13.v20161014]
    at org.jetbrains.ktor.servlet.ServletReadChannel.read(ServletReadChannel.kt:45) ~[ktor-servlet-0.2.3.jar:0.2.3]
    at org.jetbrains.ktor.nio.AsyncReadChannelAdapterStream.read(Channels.kt:114) ~[ktor-core-0.2.3.jar:0.2.3]
    at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:284) ~[na:1.8.0_60]
    at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:326) ~[na:1.8.0_60]
    at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:178) ~[na:1.8.0_60]
    at java.io.InputStreamReader.read(InputStreamReader.java:184) ~[na:1.8.0_60]
    at java.io.Reader.read(Reader.java:140) ~[na:1.8.0_60]
    at kotlin.io.TextStreamsKt.copyTo(ReadWrite.kt:116) ~[kotlin-stdlib-1.0.5.jar:1.0.5]
    at kotlin.io.TextStreamsKt.copyTo$default(ReadWrite.kt:113) ~[kotlin-stdlib-1.0.5.jar:1.0.5]
    at kotlin.io.TextStreamsKt.readText(ReadWrite.kt:100) ~[kotlin-stdlib-1.0.5.jar:1.0.5]
    at org.jetbrains.ktor.request.RequestContent$contentAsString$2.invoke(RequestContent.kt:11) ~[ktor-core-0.2.3.jar:0.2.3]
    at org.jetbrains.ktor.request.RequestContent$contentAsString$2.invoke(RequestContent.kt:10) ~[ktor-core-0.2.3.jar:0.2.3]
    at kotlin.SynchronizedLazyImpl.getValue(Lazy.kt:131) ~[kotlin-stdlib-1.0.5.jar:1.0.5]
    at org.jetbrains.ktor.request.RequestContent.getContentAsString(RequestContent.kt) ~[ktor-core-0.2.3.jar:0.2.3]
    at org.jetbrains.ktor.request.RequestContent.get(RequestContent.kt:37) ~[ktor-core-0.2.3.jar:0.2.3]
    at org.jetbrains.ktor.request.RequestContent$computedValuesMap$2.invoke(RequestContent.kt:49) ~[ktor-core-0.2.3.jar:0.2.3]
    at org.jetbrains.ktor.request.RequestContent$computedValuesMap$2.invoke(RequestContent.kt:10) ~[ktor-core-0.2.3.jar:0.2.3]
    at kotlin.SynchronizedLazyImpl.getValue(Lazy.kt:131) ~[kotlin-stdlib-1.0.5.jar:1.0.5]
    at org.jetbrains.ktor.request.RequestContent.getComputedValuesMap(RequestContent.kt) ~[ktor-core-0.2.3.jar:0.2.3]
    at org.jetbrains.ktor.request.RequestContent.get(RequestContent.kt:38) ~[ktor-core-0.2.3.jar:0.2.3]
    at org.jetbrains.ktor.host.BaseApplicationCall$parameters$2.invoke(BaseApplicationCall.kt:185) ~[ktor-hosts-common-0.2.3.jar:0.2.3]
    at org.jetbrains.ktor.host.BaseApplicationCall$parameters$2.invoke(BaseApplicationCall.kt:13) ~[ktor-hosts-common-0.2.3.jar:0.2.3]
    at kotlin.SynchronizedLazyImpl.getValue(Lazy.kt:131) ~[kotlin-stdlib-1.0.5.jar:1.0.5]
    at org.jetbrains.ktor.host.BaseApplicationCall.getParameters(BaseApplicationCall.kt) ~[ktor-hosts-common-0.2.3.jar:0.2.3]
    at org.jetbrains.ktor.routing.Routing.interceptor(Routing.kt:10) ~[ktor-core-0.2.3.jar:0.2.3]
    at org.jetbrains.ktor.routing.Routing.access$interceptor(Routing.kt:7) ~[ktor-core-0.2.3.jar:0.2.3]
    at org.jetbrains.ktor.routing.Routing$Feature$install$1.invoke(Routing.kt:28) ~[ktor-core-0.2.3.jar:0.2.3]
    at org.jetbrains.ktor.routing.Routing$Feature$install$1.invoke(Routing.kt:23) ~[ktor-core-0.2.3.jar:0.2.3]
    at org.jetbrains.ktor.pipeline.PipelineMachine.runAction(PipelineMachine.kt:113) [ktor-core-0.2.3.jar:0.2.3]
    at org.jetbrains.ktor.pipeline.PipelineMachine.loop(PipelineMachine.kt:105) [ktor-core-0.2.3.jar:0.2.3]
    at org.jetbrains.ktor.pipeline.PipelineMachine.proceed(PipelineMachine.kt:25) [ktor-core-0.2.3.jar:0.2.3]
    at org.jetbrains.ktor.pipeline.PipelineMachine.execute(PipelineMachine.kt:16) [ktor-core-0.2.3.jar:0.2.3]
    at org.jetbrains.ktor.pipeline.AsyncKt$executeOn$1.get(Async.kt:30) [ktor-core-0.2.3.jar:0.2.3]
    at org.jetbrains.ktor.pipeline.AsyncKt$executeOn$1.get(Async.kt) [ktor-core-0.2.3.jar:0.2.3]
    at java.util.concurrent.CompletableFuture$AsyncSupply.run(CompletableFuture.java:1590) [na:1.8.0_60]
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) [na:1.8.0_60]
    at java.util.concurrent.FutureTask.run(FutureTask.java:266) [na:1.8.0_60]
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180) [na:1.8.0_60]
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293) [na:1.8.0_60]
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [na:1.8.0_60]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [na:1.8.0_60]
    at java.lang.Thread.run(Thread.java:745) [na:1.8.0_60]

Documentation to use with Kotlin 1.1 EAP?

I tried to get it working with both the Netty and Jetty embedded server. I am using Ktor 0.2.4 and Kotlin 1.1-M03.

import org.jetbrains.ktor.application.call
import org.jetbrains.ktor.application.install
import org.jetbrains.ktor.features.DefaultHeaders
import org.jetbrains.ktor.jetty.embeddedJettyServer
import org.jetbrains.ktor.logging.CallLogging
import org.jetbrains.ktor.response.respondText
import org.jetbrains.ktor.routing.Routing
import org.jetbrains.ktor.routing.get

fun main(args: Array<String>) = embeddedJettyServer {
	install(DefaultHeaders)
	install(CallLogging)
	install(Routing) {
		get("/") {
			call.respondText("Hello, World!")
		}
	}
}.start()
2016-12-09 20:23:11.000 [main] INFO  org.eclipse.jetty.util.log - Logging initialized @426ms
2016-12-09 20:23:11.064 [main] TRACE embedded - Starting server...
2016-12-09 20:23:11.065 [main] INFO  org.eclipse.jetty.server.Server - jetty-9.3.13.v20161014
2016-12-09 20:23:11.126 [main] INFO  o.e.jetty.server.AbstractConnector - Started ServerConnector@69a10787{HTTP/1.1,[http/1.1, h2c, h2c-17, h2c-16, h2c-15, h2c-14]}{0.0.0.0:80}
2016-12-09 20:23:11.126 [main] INFO  org.eclipse.jetty.server.Server - Started @555ms
2016-12-09 20:23:11.126 [main] TRACE embedded - Server running.
2016-12-09 20:23:13.826 [ktor-pool-1-thread-1] ERROR embedded - null: GET - /
java.lang.IncompatibleClassChangeError: class kotlin.reflect.jvm.internal.KFunctionImpl has interface kotlin.jvm.internal.FunctionImpl as super class
	at java.lang.ClassLoader.defineClass1(Native Method) ~[na:1.8.0_112]
	at java.lang.ClassLoader.defineClass(ClassLoader.java:763) ~[na:1.8.0_112]
	at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142) ~[na:1.8.0_112]
	at java.net.URLClassLoader.defineClass(URLClassLoader.java:467) ~[na:1.8.0_112]
	at java.net.URLClassLoader.access$100(URLClassLoader.java:73) ~[na:1.8.0_112]
	at java.net.URLClassLoader$1.run(URLClassLoader.java:368) ~[na:1.8.0_112]
	at java.net.URLClassLoader$1.run(URLClassLoader.java:362) ~[na:1.8.0_112]
	at java.security.AccessController.doPrivileged(Native Method) ~[na:1.8.0_112]
	at java.net.URLClassLoader.findClass(URLClassLoader.java:361) ~[na:1.8.0_112]
	at java.lang.ClassLoader.loadClass(ClassLoader.java:424) ~[na:1.8.0_112]
	at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331) ~[na:1.8.0_112]
	at java.lang.ClassLoader.loadClass(ClassLoader.java:357) ~[na:1.8.0_112]
	at kotlin.reflect.jvm.internal.KDeclarationContainerImpl$getMembers$visitor$1.visitFunctionDescriptor(KDeclarationContainerImpl.kt:68) ~[kotlin-reflect-1.0.5-2.jar:1.0.5-2]
	at kotlin.reflect.jvm.internal.KDeclarationContainerImpl$getMembers$visitor$1.visitFunctionDescriptor(KDeclarationContainerImpl.kt:52) ~[kotlin-reflect-1.0.5-2.jar:1.0.5-2]
	at kotlin.reflect.jvm.internal.impl.descriptors.impl.FunctionDescriptorImpl.accept(FunctionDescriptorImpl.java:613) ~[kotlin-reflect-1.0.5-2.jar:1.0.5-2]
	at kotlin.reflect.jvm.internal.KDeclarationContainerImpl$getMembers$2.invoke(KDeclarationContainerImpl.kt:81) ~[kotlin-reflect-1.0.5-2.jar:1.0.5-2]
	at kotlin.reflect.jvm.internal.KDeclarationContainerImpl$getMembers$2.invoke(KDeclarationContainerImpl.kt:33) ~[kotlin-reflect-1.0.5-2.jar:1.0.5-2]
	at kotlin.sequences.TransformingSequence$iterator$1.next(Sequences.kt:137) ~[kotlin-stdlib-1.1-M03.jar:1.1-M03]
	at kotlin.sequences.FilteringSequence$iterator$1.calcNext(Sequences.kt:98) ~[kotlin-stdlib-1.1-M03.jar:1.1-M03]
	at kotlin.sequences.FilteringSequence$iterator$1.hasNext(Sequences.kt:121) ~[kotlin-stdlib-1.1-M03.jar:1.1-M03]
	at kotlin.sequences.FilteringSequence$iterator$1.calcNext(Sequences.kt:97) ~[kotlin-stdlib-1.1-M03.jar:1.1-M03]
	at kotlin.sequences.FilteringSequence$iterator$1.hasNext(Sequences.kt:121) ~[kotlin-stdlib-1.1-M03.jar:1.1-M03]
	at kotlin.sequences.SequencesKt___SequencesKt.toCollection(_Sequences.kt:533) ~[kotlin-stdlib-1.1-M03.jar:1.1-M03]
	at kotlin.sequences.SequencesKt___SequencesKt.toMutableList(_Sequences.kt:557) ~[kotlin-stdlib-1.1-M03.jar:1.1-M03]
	at kotlin.sequences.SequencesKt___SequencesKt.toList(_Sequences.kt:550) ~[kotlin-stdlib-1.1-M03.jar:1.1-M03]
	at kotlin.reflect.KClasses.getMemberProperties(KClasses.kt:142) ~[kotlin-reflect-1.0.5-2.jar:1.1-M03]
	at org.jetbrains.ktor.http.HttpStatusCode.<clinit>(HttpStatusCode.kt:65) ~[ktor-core-0.2.4.jar:0.2.4]
	at org.jetbrains.ktor.host.BaseApplicationCall.commit(BaseApplicationCall.kt:24) ~[ktor-hosts-common-0.2.4.jar:0.2.4]
	at org.jetbrains.ktor.host.BaseApplicationCall.handleFinalContent(BaseApplicationCall.kt:87) ~[ktor-hosts-common-0.2.4.jar:0.2.4]
	at org.jetbrains.ktor.host.BaseApplicationCall$1.invoke(BaseApplicationCall.kt:47) ~[ktor-hosts-common-0.2.4.jar:0.2.4]
	at org.jetbrains.ktor.host.BaseApplicationCall$1.invoke(BaseApplicationCall.kt:13) ~[ktor-hosts-common-0.2.4.jar:0.2.4]
	at org.jetbrains.ktor.pipeline.PipelineMachine.runAction(PipelineMachine.kt:111) [ktor-core-0.2.4.jar:0.2.4]
	at org.jetbrains.ktor.pipeline.PipelineMachine.loop(PipelineMachine.kt:103) [ktor-core-0.2.4.jar:0.2.4]
	at org.jetbrains.ktor.pipeline.PipelineMachine.proceed(PipelineMachine.kt:25) [ktor-core-0.2.4.jar:0.2.4]
	at org.jetbrains.ktor.pipeline.PipelineMachine.execute(PipelineMachine.kt:16) [ktor-core-0.2.4.jar:0.2.4]
	at org.jetbrains.ktor.pipeline.AsyncKt$executeOn$1.get(Async.kt:30) [ktor-core-0.2.4.jar:0.2.4]
	at org.jetbrains.ktor.pipeline.AsyncKt$executeOn$1.get(Async.kt) [ktor-core-0.2.4.jar:0.2.4]
	at java.util.concurrent.CompletableFuture$AsyncSupply.run(CompletableFuture.java:1590) [na:1.8.0_112]
	at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) [na:1.8.0_112]
	at java.util.concurrent.FutureTask.run(FutureTask.java:266) [na:1.8.0_112]
	at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180) [na:1.8.0_112]
	at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293) [na:1.8.0_112]
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [na:1.8.0_112]
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [na:1.8.0_112]
	at java.lang.Thread.run(Thread.java:745) [na:1.8.0_112]

gradle is unable to resolve dependencies

When trying to install ktor through gradle, it is unable to resolve dependencies:

gradle output:

$ gradle --stacktrace
:compileKotlin

FAILURE: Build failed with an exception.

* What went wrong:
Could not resolve all dependencies for configuration ':compile'.
> Could not find org.jetbrains.kotlinx:kotlinx-support-jdk8:0.1-alpha-2.
  Searched in the following locations:
      https://repo1.maven.org/maven2/org/jetbrains/kotlinx/kotlinx-support-jdk8/0.1-alpha-2/kotlinx-support-jdk8-0.1-alpha-2.pom
      https://repo1.maven.org/maven2/org/jetbrains/kotlinx/kotlinx-support-jdk8/0.1-alpha-2/kotlinx-support-jdk8-0.1-alpha-2.pom
      http://dl.bintray.com/kotlin/ktor/org/jetbrains/kotlinx/kotlinx-support-jdk8/0.1-alpha-2/kotlinx-support-jdk8-0.1-alpha-2.pom
      http://dl.bintray.com/kotlin/ktor/org/jetbrains/kotlinx/kotlinx-support-jdk8/0.1-alpha-2/kotlinx-support-jdk8-0.1-alpha-2.pom
  Required by:
      :kotlin-blog:unspecified > org.jetbrains.ktor:ktor-core:0.2.2

* Try:
Run with --info or --debug option to get more log output.

* Exception is:
org.gradle.api.artifacts.ResolveException: Could not resolve all dependencies for configuration ':compile'.
        at org.gradle.api.internal.artifacts.ivyservice.DefaultLenientConfiguration.rethrowFailure(DefaultLenientConfiguration.java:52)
        at org.gradle.api.internal.artifacts.ivyservice.DefaultResolvedConfiguration.rethrowFailure(DefaultResolvedConfiguration.java:36)
        at org.gradle.api.internal.artifacts.ivyservice.SelfResolvingDependencyResolver$FilesAggregatingResolvedConfiguration.rethrowFailure(SelfResolvingDependencyResolver.java:110)
        at org.gradle.api.internal.artifacts.ivyservice.ErrorHandlingArtifactDependencyResolver$ErrorHandlingResolvedConfiguration.rethrowFailure(ErrorHandlingArtifactDependencyResolver.java:180)
        at org.gradle.api.internal.artifacts.configurations.DefaultConfiguration$ConfigurationFileCollection.getFiles(DefaultConfiguration.java:467)
        at org.gradle.api.internal.artifacts.configurations.DefaultConfiguration.getFiles(DefaultConfiguration.java:218)
        at org.gradle.api.internal.artifacts.configurations.DefaultConfiguration_Decorated.getFiles(Unknown Source)
        at org.gradle.api.internal.file.collections.DefaultFileCollectionResolveContext$FileTreeConverter.convertInto(DefaultFileCollectionResolveContext.java:191)
        at org.gradle.api.internal.file.collections.DefaultFileCollectionResolveContext.doResolve(DefaultFileCollectionResolveContext.java:103)
        at org.gradle.api.internal.file.collections.DefaultFileCollectionResolveContext.resolveAsFileTrees(DefaultFileCollectionResolveContext.java:75)
        at org.gradle.api.internal.file.collections.DefaultFileCollectionResolveContext$FileTreeConverter.convertInto(DefaultFileCollectionResolveContext.java:182)
        at org.gradle.api.internal.file.collections.DefaultFileCollectionResolveContext.doResolve(DefaultFileCollectionResolveContext.java:98)
        at org.gradle.api.internal.file.collections.DefaultFileCollectionResolveContext.resolveAsFileTrees(DefaultFileCollectionResolveContext.java:75)
        at org.gradle.api.internal.file.CompositeFileCollection$1.resolve(CompositeFileCollection.java:88)
        at org.gradle.api.internal.file.CompositeFileCollection.getSourceCollections(CompositeFileCollection.java:143)
        at org.gradle.api.internal.file.CompositeFileTree.getSourceCollections(CompositeFileTree.java:30)
        at org.gradle.api.internal.file.CompositeFileCollection.getFiles(CompositeFileCollection.java:38)
        at org.gradle.api.internal.changedetection.state.DefaultFileCollectionSnapshotter.snapshot(DefaultFileCollectionSnapshotter.java:47)
        at org.gradle.api.internal.changedetection.rules.TaskUpToDateState.<init>(TaskUpToDateState.java:55)
        at org.gradle.api.internal.changedetection.changes.DefaultTaskArtifactStateRepository$TaskArtifactStateImpl.getStates(DefaultTaskArtifactStateRepository.java:126)
        at org.gradle.api.internal.changedetection.changes.DefaultTaskArtifactStateRepository$TaskArtifactStateImpl.isUpToDate(DefaultTaskArtifactStateRepository.java:69)
        at org.gradle.api.internal.tasks.execution.SkipUpToDateTaskExecuter.execute(SkipUpToDateTaskExecuter.java:52)
        at org.gradle.api.internal.tasks.execution.ValidatingTaskExecuter.execute(ValidatingTaskExecuter.java:58)
        at org.gradle.api.internal.tasks.execution.SkipEmptySourceFilesTaskExecuter.execute(SkipEmptySourceFilesTaskExecuter.java:42)
        at org.gradle.api.internal.tasks.execution.SkipTaskWithNoActionsExecuter.execute(SkipTaskWithNoActionsExecuter.java:52)
        at org.gradle.api.internal.tasks.execution.SkipOnlyIfTaskExecuter.execute(SkipOnlyIfTaskExecuter.java:53)
        at org.gradle.api.internal.tasks.execution.ExecuteAtMostOnceTaskExecuter.execute(ExecuteAtMostOnceTaskExecuter.java:43)
        at org.gradle.api.internal.AbstractTask.executeWithoutThrowingTaskFailure(AbstractTask.java:310)
        at org.gradle.execution.taskgraph.AbstractTaskPlanExecutor$TaskExecutorWorker.executeTask(AbstractTaskPlanExecutor.java:79)
        at org.gradle.execution.taskgraph.AbstractTaskPlanExecutor$TaskExecutorWorker.processTask(AbstractTaskPlanExecutor.java:63)
        at org.gradle.execution.taskgraph.AbstractTaskPlanExecutor$TaskExecutorWorker.run(AbstractTaskPlanExecutor.java:51)
        at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor.process(DefaultTaskPlanExecutor.java:23)
        at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter.execute(DefaultTaskGraphExecuter.java:88)
        at org.gradle.execution.SelectedTaskExecutionAction.execute(SelectedTaskExecutionAction.java:37)
        at org.gradle.execution.DefaultBuildExecuter.execute(DefaultBuildExecuter.java:62)
        at org.gradle.execution.DefaultBuildExecuter.access$200(DefaultBuildExecuter.java:23)
        at org.gradle.execution.DefaultBuildExecuter$2.proceed(DefaultBuildExecuter.java:68)
        at org.gradle.execution.DryRunBuildExecutionAction.execute(DryRunBuildExecutionAction.java:32)
        at org.gradle.execution.DefaultBuildExecuter.execute(DefaultBuildExecuter.java:62)
        at org.gradle.execution.DefaultBuildExecuter.execute(DefaultBuildExecuter.java:55)
        at org.gradle.initialization.DefaultGradleLauncher.doBuildStages(DefaultGradleLauncher.java:149)
        at org.gradle.initialization.DefaultGradleLauncher.doBuild(DefaultGradleLauncher.java:106)
        at org.gradle.initialization.DefaultGradleLauncher.run(DefaultGradleLauncher.java:86)
        at org.gradle.launcher.exec.InProcessBuildActionExecuter$DefaultBuildController.run(InProcessBuildActionExecuter.java:90)
        at org.gradle.tooling.internal.provider.ExecuteBuildActionRunner.run(ExecuteBuildActionRunner.java:28)
        at org.gradle.launcher.exec.ChainingBuildActionRunner.run(ChainingBuildActionRunner.java:35)
        at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:41)
        at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:28)
        at org.gradle.launcher.exec.DaemonUsageSuggestingBuildActionExecuter.execute(DaemonUsageSuggestingBuildActionExecuter.java:50)
        at org.gradle.launcher.exec.DaemonUsageSuggestingBuildActionExecuter.execute(DaemonUsageSuggestingBuildActionExecuter.java:27)
        at org.gradle.launcher.cli.RunBuildAction.run(RunBuildAction.java:40)
        at org.gradle.internal.Actions$RunnableActionAdapter.execute(Actions.java:169)
        at org.gradle.launcher.cli.CommandLineActionFactory$ParseAndBuildAction.execute(CommandLineActionFactory.java:237)
        at org.gradle.launcher.cli.CommandLineActionFactory$ParseAndBuildAction.execute(CommandLineActionFactory.java:210)
        at org.gradle.launcher.cli.JavaRuntimeValidationAction.execute(JavaRuntimeValidationAction.java:35)
        at org.gradle.launcher.cli.JavaRuntimeValidationAction.execute(JavaRuntimeValidationAction.java:24)
        at org.gradle.launcher.cli.CommandLineActionFactory$WithLogging.execute(CommandLineActionFactory.java:206)
        at org.gradle.launcher.cli.CommandLineActionFactory$WithLogging.execute(CommandLineActionFactory.java:169)
        at org.gradle.launcher.cli.ExceptionReportingAction.execute(ExceptionReportingAction.java:33)
        at org.gradle.launcher.cli.ExceptionReportingAction.execute(ExceptionReportingAction.java:22)
        at org.gradle.launcher.Main.doAction(Main.java:33)
        at org.gradle.launcher.bootstrap.EntryPoint.run(EntryPoint.java:45)
        at org.gradle.launcher.bootstrap.ProcessBootstrap.runNoExit(ProcessBootstrap.java:54)
        at org.gradle.launcher.bootstrap.ProcessBootstrap.run(ProcessBootstrap.java:35)
        at org.gradle.launcher.GradleMain.main(GradleMain.java:23)
Caused by: org.gradle.internal.resolve.ModuleVersionNotFoundException: Could not find org.jetbrains.kotlinx:kotlinx-support-jdk8:0.1-alpha-2.
Searched in the following locations:
    https://repo1.maven.org/maven2/org/jetbrains/kotlinx/kotlinx-support-jdk8/0.1-alpha-2/kotlinx-support-jdk8-0.1-alpha-2.pom
    https://repo1.maven.org/maven2/org/jetbrains/kotlinx/kotlinx-support-jdk8/0.1-alpha-2/kotlinx-support-jdk8-0.1-alpha-2.pom
    http://dl.bintray.com/kotlin/ktor/org/jetbrains/kotlinx/kotlinx-support-jdk8/0.1-alpha-2/kotlinx-support-jdk8-0.1-alpha-2.pom
    http://dl.bintray.com/kotlin/ktor/org/jetbrains/kotlinx/kotlinx-support-jdk8/0.1-alpha-2/kotlinx-support-jdk8-0.1-alpha-2.pom
Required by:
    :kotlin-blog:unspecified > org.jetbrains.ktor:ktor-core:0.2.2
        at org.gradle.internal.resolve.result.DefaultBuildableComponentResolveResult.notFound(DefaultBuildableComponentResolveResult.java:35)
        at org.gradle.api.internal.artifacts.ivyservice.ivyresolve.RepositoryChainDependencyResolver.resolve(RepositoryChainDependencyResolver.java:86)
        at org.gradle.api.internal.artifacts.ivyservice.ivyresolve.RepositoryChainAdapter.resolve(RepositoryChainAdapter.java:69)
        at org.gradle.api.internal.artifacts.ivyservice.clientmodule.ClientModuleResolver.resolve(ClientModuleResolver.java:44)
        at org.gradle.api.internal.artifacts.ivyservice.resolveengine.graph.DependencyGraphBuilder$ModuleVersionResolveState.resolve(DependencyGraphBuilder.java:576)
        at org.gradle.api.internal.artifacts.ivyservice.resolveengine.graph.DependencyGraphBuilder$ModuleVersionResolveState.getMetaData(DependencyGraphBuilder.java:586)
        at org.gradle.api.internal.artifacts.ivyservice.resolveengine.graph.DependencyGraphBuilder$DependencyEdge.calculateTargetConfigurations(DependencyGraphBuilder.java:271)
        at org.gradle.api.internal.artifacts.ivyservice.resolveengine.graph.DependencyGraphBuilder$DependencyEdge.attachToTargetConfigurations(DependencyGraphBuilder.java:245)
        at org.gradle.api.internal.artifacts.ivyservice.resolveengine.graph.DependencyGraphBuilder.traverseGraph(DependencyGraphBuilder.java:155)
        at org.gradle.api.internal.artifacts.ivyservice.resolveengine.graph.DependencyGraphBuilder.resolveDependencyGraph(DependencyGraphBuilder.java:93)
        at org.gradle.api.internal.artifacts.ivyservice.resolveengine.graph.DependencyGraphBuilder.resolve(DependencyGraphBuilder.java:83)
        at org.gradle.api.internal.artifacts.ivyservice.resolveengine.DefaultDependencyResolver$1.execute(DefaultDependencyResolver.java:125)
        at org.gradle.api.internal.artifacts.ivyservice.resolveengine.DefaultDependencyResolver$1.execute(DefaultDependencyResolver.java:90)
        at org.gradle.internal.Transformers$4.transform(Transformers.java:137)
        at org.gradle.api.internal.artifacts.ivyservice.DefaultIvyContextManager.withIvy(DefaultIvyContextManager.java:61)
        at org.gradle.api.internal.artifacts.ivyservice.DefaultIvyContextManager.withIvy(DefaultIvyContextManager.java:39)
        at org.gradle.api.internal.artifacts.ivyservice.resolveengine.DefaultDependencyResolver.resolve(DefaultDependencyResolver.java:90)
        at org.gradle.api.internal.artifacts.ivyservice.CacheLockingArtifactDependencyResolver$1.run(CacheLockingArtifactDependencyResolver.java:42)
        at org.gradle.internal.Factories$1.create(Factories.java:22)
        at org.gradle.cache.internal.DefaultCacheAccess.useCache(DefaultCacheAccess.java:192)
        at org.gradle.cache.internal.DefaultCacheAccess.useCache(DefaultCacheAccess.java:175)
        at org.gradle.cache.internal.DefaultPersistentDirectoryStore.useCache(DefaultPersistentDirectoryStore.java:106)
        at org.gradle.cache.internal.DefaultCacheFactory$ReferenceTrackingCache.useCache(DefaultCacheFactory.java:187)
        at org.gradle.api.internal.artifacts.ivyservice.DefaultCacheLockingManager.useCache(DefaultCacheLockingManager.java:64)
        at org.gradle.api.internal.artifacts.ivyservice.CacheLockingArtifactDependencyResolver.resolve(CacheLockingArtifactDependencyResolver.java:40)
        at org.gradle.api.internal.artifacts.ivyservice.SelfResolvingDependencyResolver.resolve(SelfResolvingDependencyResolver.java:45)
        at org.gradle.api.internal.artifacts.ivyservice.ShortcircuitEmptyConfigsArtifactDependencyResolver.resolve(ShortcircuitEmptyConfigsArtifactDependencyResolver.java:58)
        at org.gradle.api.internal.artifacts.ivyservice.ErrorHandlingArtifactDependencyResolver.resolve(ErrorHandlingArtifactDependencyResolver.java:47)
        at org.gradle.api.internal.artifacts.ivyservice.DefaultConfigurationResolver.resolve(DefaultConfigurationResolver.java:46)
        at org.gradle.api.internal.artifacts.configurations.DefaultConfiguration.resolveNow(DefaultConfiguration.java:263)
        at org.gradle.api.internal.artifacts.configurations.DefaultConfiguration.getResolvedConfiguration(DefaultConfiguration.java:253)
        at org.gradle.api.internal.artifacts.configurations.DefaultConfiguration_Decorated.getResolvedConfiguration(Unknown Source)
        at org.gradle.api.internal.artifacts.configurations.DefaultConfiguration$ConfigurationFileCollection.getFiles(DefaultConfiguration.java:465)
        ... 60 more


BUILD FAILED

Total time: 8.983 secs

build.gradle:

buildscript {
  ext.kotlin_version = '1.0.0'
  repositories {
    mavenCentral()

  }
  dependencies {
    classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
  }
}

apply plugin: 'kotlin'
apply plugin: 'application'

mainClassName = 'blog.MainKt'

defaultTasks 'run'

repositories {
    mavenCentral()
    maven {
        url  "http://dl.bintray.com/kotlin/ktor"
    }
}

dependencies {
  compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
  compile "org.jetbrains.ktor:ktor-core:0.2.2"
  testCompile 'junit:junit:4.11'
  testCompile "org.jetbrains.kotlin:kotlin-test-junit:$kotlin_version"
}

task wrapper(type: Wrapper) {
  gradleVersion = "2.7"
}

Simplify the Automatic HEAD response feature

The Readme.md indicates an Automatic HEAD response. It's not as automatic as one could expect. It needs the installation of HeadRequestSupport feature AND the routing of HEAD requests.

This feature:

  1. should be at least documented,
  2. ideally, easier to set up (with automatic Head handles for every get).

As a workaround to set up the Head routing for every Get mapping, you can add this extension method:

fun Route.getOrHead(path: String, body: PipelineContext<ApplicationCall>.(ApplicationCall) -> Unit): Route {
    val selector = OrRouteSelector(HttpMethodRouteSelector(HttpMethod.Get),HttpMethodRouteSelector(HttpMethod.Head))
    return select(selector).route(path) { handle(body) }
}

and replace the get calls by this new function.

install(HeadRequestSupport)
routing {
    getOrHead("/foo") {
        call.respondText("Bar")
    }
}

CallLogger fails to intercept exceptions

ktor 0.2.2
CallLogger fails to properly capture exceptions (NPE, for example) and logs them instead as "trace"s.

PipelineMachine ends up in PipelineState.Succeeded state. My guess is StatusPagesKt.errorPage creates a new execution with state "Executing", which clears the "Failed" state from the pipeline".

As a side note, that whole "Pipeline" stuff is absolutely incomprehensible and hard to debug. Took me ah hour to understand it's actually an implementation of event loop. I have a bad feeling about this approach (reminds of JavaScript callback hell - highly sharded code hard to follow, complex state management), but at the very least it needs tons, TONS of documentation.

Exception in Route.handle is handled silently

Unhandled exceptions are usually printed (afaik) but the IllegalArgumentException here isnt. My guess would be it should always be printed.

class Blocking(environment: ApplicationEnvironment) : Application(environment) {
    init {
        routing {
            method(HttpMethod.Post){
                route("/exception") {
                    handle {
                        println("exception")
                        throw IllegalArgumentException()
                    }
                }
                route("/exception2") {
                    handle {
                        println("exception2")
                        subject.respondWrite {
                            throw IllegalArgumentException()
                        }
                    }
                }
            }
        }
    }
}

class ExceptionEater {

    @Test
    fun foo(){
        val port = 44003
        val appHostConfig = applicationHostConfig { connector { this.port = port } }
        val appEnv = BasicApplicationEnvironment(javaClass.classLoader, SLF4JApplicationLog("KTorTest"), MapApplicationConfig(
                "ktor.application.class" to Blocking::class.qualifiedName!!
        ))
        val jetty = JettyApplicationHost(appHostConfig, appEnv)
        jetty.start()
        val paths = listOf("exception", "exception2")
        val e = Executors.newCachedThreadPool()
        paths.map { path ->
            e.submit(Callable {
                val c = URL("http://localhost:$port/$path").openConnection() as HttpURLConnection
                c.doOutput = true
                c.outputStream.apply {
                    write("Foo".toByteArray(StandardCharsets.UTF_8))
                    flush()
                }
                c.inputStream.bufferedReader().readLine().apply {
                    println("Done")
                }
            })
        }

        TimeUnit.SECONDS.sleep(10)
    }
}

Implement proper unhandled exception handling strategy

If exception happens in ktor and is not handled by an interceptor such as StatusPages, it should propagate up to host and be handled there without using any ktor facilities like response pipeline. The reason is that we don't know which part of the system were at fault and it could very well be response pipeline itself. So unhandled exception should be propagated to the host-specific facilities and responded with 500 status code natively there.

Note, that it would make 500 Internal Server Error status produced in this case not interceptable by StatusPage feature on a per code basis, but exception filter in the same feature can be installed on Throwable and do pretty much any custom handling there. At this moment exception would be considered handled and won't be part of this issue.

Clean various `parameters` API

  • do not use host's parameters API
  • parse query parameters manually on all hosts
  • rename ApplicationRequest.parameters → queryParameters
  • Use request.content.get() to get form parameters
  • ApplicationCall.values (renamed from parameters) should combine them all
    • routing adds own path-bound parameters

Clean `response` API

On an ApplicationCall there are

  • response property which is ApplicationResponse
  • respond property which is ResponsePipeline
  • respond function which executes a subject on a pipeline

We need to figure our better non-confusing APIs.

maven/gradle access of ktor-core does not work

I keep getting a RuntimeException in the repo indexing. Some Google results suggest that that is an Intellij IDEA issue. Anyone else had that problem?

I use a 2017 version of Idea, without an external gradle installation. I tried version LATEST as well as some version numbers. Did anyone integrate ktor successfully with Maven/Gradle? I would be grateful for any hint because this seems to be a really useful project.

Routing: wildcard route handler couldn't fallback to root

install(Routing) {
        get("/") {
            call.respondText("Hello, World!")
        }
        get("/{...}") {
            if (call.request.uri != "/") {
                call.respond(call.request.uri)
            }
        }
    }

Request to / results 404 Not found instead of 200 OK with "Hello, World!" content

 curl 'http://localhost:8080/aa' 
/aa
 curl 'http://localhost:8080/'   
<H1>404 Not Found</H1>Not found: /

autoreload doesn't work for classnames

The wiki page says "For now watch keys are just strings that are matched with contains against path to classes/jars of the loaded application." To me, that wording suggests I could use the pathname of a class or a package.

If I try to watch using a substring from a package name (eg "web" from org.example.web), it doesn't work (unless that substring happens to be part of the classpath entry), with this misleading warning:

Application.Loader - No ktor.deployment.watch patterns specified: hot reload is disabled

I think this would be clearer (in the wiki):
"For now watch keys are just substrings that are matched with contains against classpath entries of the loaded application, such as a jar name or a project directory name."

BadMessageException: 400: Bad Request

Please provide some simple sample project that isn't dependant from the whole repository. For a rookie Getting started isn't enough to start Hello Word. I'm getting this when trying to access http://localhost:8080/ and don't know why

DEBUG org.eclipse.jetty.http.HttpParser - Parse exception: HttpParser{s=END,0 of 0} for HttpChannelOverHttp@37cc43a2{r=1,c=false,a=IDLE,uri=//localhost:8080/}
org.eclipse.jetty.http.BadMessageException: 400: Bad Request
at org.eclipse.jetty.http.HttpParser.parseNext(HttpParser.java:1464)
at org.eclipse.jetty.server.HttpConnection.parseRequestBuffer(HttpConnection.java:350)
at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:234)
at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:279)
at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:110)
at org.eclipse.jetty.io.ChannelEndPoint$2.run(ChannelEndPoint.java:124)
at org.eclipse.jetty.util.thread.Invocable.invokePreferred(Invocable.java:122)
at org.eclipse.jetty.util.thread.strategy.ExecutingExecutionStrategy.invoke(ExecutingExecutionStrategy.java:58)
at org.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume.produceConsume(ExecuteProduceConsume.java:201)
at org.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume.run(ExecuteProduceConsume.java:133)
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:672)
at org.eclipse.jetty.util.thread.QueuedThreadPool$2.run(QueuedThreadPool.java:590)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.AbstractMethodError: Method org/eclipse/jetty/server/HttpChannelOverHttp.contentComplete()Z is abstract
at org.eclipse.jetty.server.HttpChannelOverHttp.contentComplete(HttpChannelOverHttp.java)
at org.eclipse.jetty.http.HttpParser.handleHeaderContentMessage(HttpParser.java:597)
at org.eclipse.jetty.http.HttpParser.parseFields(HttpParser.java:1115)
at org.eclipse.jetty.http.HttpParser.parseNext(HttpParser.java:1369)
... 12 common frames omitted

Locations: Support trailing /

At the moment you cannot create hrefs from a location with trailing /:
/somepath/ as it would end up being /somepath

This should of cause also work for nested Locations, so i could do:

@location("/somepath/") class SomeLocation{
    @location("/nested/") class Nested
}

and get /somepath/and /somepath/nested/

ServletConfig has not been initialized when deploying to Jetty

I've been playing with this over the weekend and have got it running in an embedded context and using the org.jetbrains.ktor.jetty.DevelopmentHost

The next step was to deploy to a Jetty instance, and that's where I'm running into this problem. It's been a while since I've played with a WAR, so maybe I'm doing something obviously wrong.

web.xml
whole project

2017-02-12 18:46:56.210:WARN:oejs.HttpChannel:qtp4076014-11: /homeseer-brains/
javax.servlet.ServletException: org.eclipse.jetty.servlet.ServletHolder$1: java.lang.IllegalStateException: ServletConfig has not been initialized
	at org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:138)
	at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:132)
	at org.eclipse.jetty.server.Server.handle(Server.java:564)
	at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:320)
	at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:251)
	at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:279)
	at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:112)
	at org.eclipse.jetty.io.ChannelEndPoint$2.run(ChannelEndPoint.java:124)
	at org.eclipse.jetty.util.thread.Invocable.invokePreferred(Invocable.java:122)
	at org.eclipse.jetty.util.thread.strategy.ExecutingExecutionStrategy.invoke(ExecutingExecutionStrategy.java:58)
	at org.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume.produceConsume(ExecuteProduceConsume.java:201)
	at org.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume.run(ExecuteProduceConsume.java:133)
	at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:672)
	at org.eclipse.jetty.util.thread.QueuedThreadPool$2.run(QueuedThreadPool.java:590)
	at java.lang.Thread.run(Thread.java:745)
Caused by:
org.eclipse.jetty.servlet.ServletHolder$1: java.lang.IllegalStateException: ServletConfig has not been initialized
	at org.eclipse.jetty.servlet.ServletHolder.makeUnavailable(ServletHolder.java:596)
	at org.eclipse.jetty.servlet.ServletHolder.initServlet(ServletHolder.java:648)
	at org.eclipse.jetty.servlet.ServletHolder.getServlet(ServletHolder.java:498)
	at org.eclipse.jetty.servlet.ServletHolder.ensureInstance(ServletHolder.java:785)
	at org.eclipse.jetty.servlet.ServletHolder.prepare(ServletHolder.java:770)
	at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:538)
	at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143)
	at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:548)
	at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:132)
	at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:190)
	at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:1584)
	at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:188)
	at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1228)
	at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:168)
	at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:481)
	at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:1553)
	at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:166)
	at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1130)
	at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)
	at org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:213)
	at org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:118)
	at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:132)
	at org.eclipse.jetty.server.Server.handle(Server.java:564)
	at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:320)
	at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:251)
	at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:279)
	at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:112)
	at org.eclipse.jetty.io.ChannelEndPoint$2.run(ChannelEndPoint.java:124)
	at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:672)
	at org.eclipse.jetty.util.thread.QueuedThreadPool$2.run(QueuedThreadPool.java:590)
	at java.lang.Thread.run(Thread.java:745)
Caused by:
java.lang.IllegalStateException: ServletConfig has not been initialized
	at javax.servlet.GenericServlet.getServletContext(GenericServlet.java:199)
	at org.jetbrains.ktor.servlet.ServletApplicationHost$loader$2.invoke(ServletApplicationHost.kt:15)
	at org.jetbrains.ktor.servlet.ServletApplicationHost$loader$2.invoke(ServletApplicationHost.kt:13)
	at kotlin.SynchronizedLazyImpl.getValue(Lazy.kt:130)
	at org.jetbrains.ktor.servlet.ServletApplicationHost.getLoader(ServletApplicationHost.kt)
	at org.jetbrains.ktor.servlet.ServletApplicationHost.<init>(ServletApplicationHost.kt:36)
	at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
	at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
	at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
	at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
	at java.lang.Class.newInstance(Class.java:442)
	at org.eclipse.jetty.server.handler.ContextHandler$Context.createInstance(ContextHandler.java:2510)
	at org.eclipse.jetty.servlet.ServletContextHandler$Context.createServlet(ServletContextHandler.java:1326)
	at org.eclipse.jetty.servlet.ServletHolder.newInstance(ServletHolder.java:1273)
	at org.eclipse.jetty.servlet.ServletHolder.initServlet(ServletHolder.java:614)
	at org.eclipse.jetty.servlet.ServletHolder.getServlet(ServletHolder.java:498)
	at org.eclipse.jetty.servlet.ServletHolder.ensureInstance(ServletHolder.java:785)
	at org.eclipse.jetty.servlet.ServletHolder.prepare(ServletHolder.java:770)
	at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:538)
	at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143)
	at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:548)
	at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:132)
	at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:190)
	at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:1584)
	at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:188)
	at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1228)
	at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:168)
	at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:481)
	at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:1553)
	at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:166)
	at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1130)
	at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)
	at org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:213)
	at org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:118)
	at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:132)
	at org.eclipse.jetty.server.Server.handle(Server.java:564)
	at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:320)
	at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:251)
	at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:279)
	at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:112)
	at org.eclipse.jetty.io.ChannelEndPoint$2.run(ChannelEndPoint.java:124)
	at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:672)
	at org.eclipse.jetty.util.thread.QueuedThreadPool$2.run(QueuedThreadPool.java:590)
	at java.lang.Thread.run(Thread.java:745)

W: Could not expand ZIP '..../kotlinx-support-jdk8-0.3.pom'

When you compiling something with gradle dependency to ktor-core, you got this warning, but if you try to build fatJar you gonna build fail.

Sample gradle file

version '0.1-SNAPSHOT'

buildscript {
    ext.kotlin_version = '1.0.3'

    repositories {
        mavenCentral()
    }
    dependencies {
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
    }
}

apply plugin: 'java'
apply plugin: 'kotlin'

sourceCompatibility = 1.8

repositories {
    maven {
        url 'http://dl.bintray.com/kotlin/ktor'
    }
    mavenCentral()
    jcenter()
}

dependencies {
    compile 'org.jetbrains.ktor:ktor-core:0.2.2'
    compile 'org.jetbrains.ktor:ktor-netty:0.2.2'
}

task fatJar(type: Jar) {
    manifest {
        attributes "Main-Class": "MainClass"
    }
    baseName = project.name
    from {
        configurations.compile.collect {
            it.isDirectory() ? it : zipTree(it)
        }
    }
    with jar
}
FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':fatJar'.
> Could not expand ZIP '/<somePath>/kotlinx-support-jdk8-0.1-alpha-2.pom'.

InMemorySessionStorage fails with exception if the session id is invalid

The contract of the interface of session storages defines that SessiosStorage.lookup should only call the consumer if the session can be found and otherwise fail silently.

The InMemorySessionStorage throws an IllegalArgumentException is the session can not be found and thus crashes the pipeline.

https://github.com/Kotlin/ktor/blob/master/ktor-features/ktor-server-sessions/src/org/jetbrains/ktor/sessions/SessionStorage.kt#L46


private class InMemorySessionStorage : SessionStorage {
    private val sessions = ConcurrentHashMap<String, ByteArray>()

    override fun save(id: String, contentProvider: (OutputStream) -> Unit): Future<Unit> {
        val baos = ByteArrayOutputStream()
        contentProvider(baos)
        sessions[id] = baos.toByteArray()
        return CompletableFuture.completedFuture(Unit)
    }

    override fun <R> read(id: String, consumer: (InputStream) -> R): Future<R> = CompletableFuture<R>().apply {
        sessions[id]?.let { bytes -> complete(consumer(bytes.inputStream())) } ?: throw IllegalArgumentException("Session $id not found")
    }

    override fun invalidate(id: String): Future<Unit> {
        sessions.remove(id)
        return CompletableFuture.completedFuture(Unit)
    }
}

Here is a minimal test that that shows how this behavior crashes the pipeline:
https://gist.github.com/audax/ac07afbe225d0d6a04f57a9fa492bffb

CPU at 100% due to Compression feature

I didn't manage to reproduce it in a dev/integration environment but I had it in production.
The Compression feature was taking all CPU. Removing it resolved the problem.

The configuration of the feature was:

    install(Compression) {
        default()
        excludeMimeTypeMatch(ContentType.Video.Any)
    }

See above the view of the threads and the profiling of CPU.

image

image

Documentation

Hi, I would like to have some documentation of ktor before using it. The Wiki has some links with empty content.

Don't pull in logback-classic as a dependency

A number of ktor gradle artifacts specify logback-classic as a dependency, however best practice for libraries is to include something like sl4j-api, but not any specific logging implementation - to prevent an application's logs from being filled up with logging generated by a library.

The workaround is to do something like this:

    compile ('org.jetbrains.ktor:ktor-core:0.3.0') {
        exclude group : 'ch.qos.logback', module : 'logback-classic'
    }

Embedded Netty server closes immediately

import org.jetbrains.ktor.application.call
import org.jetbrains.ktor.http.ContentType
import org.jetbrains.ktor.netty.embeddedNettyServer
import org.jetbrains.ktor.response.respondText
import org.jetbrains.ktor.routing.get
import org.jetbrains.ktor.routing.routing

fun main(args: Array<String>) {
	embeddedNettyServer {
		routing {
			get("/") {
				call.respondText(ContentType.Text.Plain, "Hello, world!")
			}
		}
	}
}

And here's the logging output:

"C:\Program Files\Java\jdk1.8.0_112\bin\java" -Didea.launcher.port=7538 "-Didea.launcher.bin.path=C:\Program Files (x86)\JetBrains\IntelliJ IDEA 2016.3\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_112\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_112\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_112\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_112\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_112\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_112\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_112\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_112\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_112\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_112\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_112\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_112\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_112\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_112\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_112\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_112\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_112\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_112\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_112\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_112\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_112\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_112\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_112\jre\lib\rt.jar;D:\Desktop\CheatLife-Web\build\classes\main;D:\Desktop\CheatLife-Web\build\resources\main;C:\Users\Jire\.gradle\caches\modules-2\files-2.1\org.jetbrains.kotlin\kotlin-stdlib\1.1-M03\1c4aa4b0dab7b4c111934f34e6506812d7e974a2\kotlin-stdlib-1.1-M03.jar;C:\Users\Jire\.gradle\caches\modules-2\files-2.1\org.jetbrains.kotlinx\kotlinx.html.jvm\0.5.12\3da1a90368af646a445193dc31da6a4d9c5f0458\kotlinx.html.jvm-0.5.12.jar;C:\Users\Jire\.gradle\caches\modules-2\files-2.1\org.jetbrains.ktor\ktor-netty\0.2.4\3af06c53d0be9f5052eaffde1013613c14a87d5f\ktor-netty-0.2.4.jar;C:\Users\Jire\.gradle\caches\modules-2\files-2.1\org.jetbrains.kotlin\kotlin-runtime\1.1-M03\4069ca5d11d19708ad18b0266bb77af0c54a47a8\kotlin-runtime-1.1-M03.jar;C:\Users\Jire\.gradle\caches\modules-2\files-2.1\org.jetbrains.kotlinx\kotlinx.html.shared\0.5.12\5cb67c768cfef3c12f0d2f98916b1a0eae124ec8\kotlinx.html.shared-0.5.12-jvm.jar;C:\Users\Jire\.gradle\caches\modules-2\files-2.1\org.jetbrains.ktor\ktor-hosts-common\0.2.4\9b36e5b96bf0d3e4e743471826ed6ff43e77da83\ktor-hosts-common-0.2.4.jar;C:\Users\Jire\.gradle\caches\modules-2\files-2.1\io.netty\netty-codec-http2\4.1.5.Final\6568f4fefc2ce0a8761e5bc14d95a6ba1758be29\netty-codec-http2-4.1.5.Final.jar;C:\Users\Jire\.gradle\caches\modules-2\files-2.1\org.eclipse.jetty.alpn\alpn-api\1.1.3.v20160715\a1bf3a937f91b4c953acd13e8c9552347adc2198\alpn-api-1.1.3.v20160715.jar;C:\Users\Jire\.gradle\caches\modules-2\files-2.1\org.jetbrains.ktor\ktor-core\0.2.4\cdb24fa130d4636e793971105603f98af040e14c\ktor-core-0.2.4.jar;C:\Users\Jire\.gradle\caches\modules-2\files-2.1\org.jetbrains.kotlin\kotlin-reflect\1.0.5-2\b20effae1385355c5216c647300efe35f97aa2ae\kotlin-reflect-1.0.5-2.jar;C:\Users\Jire\.gradle\caches\modules-2\files-2.1\org.jetbrains.kotlinx\kotlinx-support-jdk8\0.3\5fe4a54228199cd21454469fb1e9ccc354c500a8\kotlinx-support-jdk8-0.3.jar;C:\Users\Jire\.gradle\caches\modules-2\files-2.1\org.slf4j\slf4j-api\1.7.21\139535a69a4239db087de9bab0bee568bf8e0b70\slf4j-api-1.7.21.jar;C:\Users\Jire\.gradle\caches\modules-2\files-2.1\ch.qos.logback\logback-classic\1.1.2\b316e9737eea25e9ddd6d88eaeee76878045c6b2\logback-classic-1.1.2.jar;C:\Users\Jire\.gradle\caches\modules-2\files-2.1\com.typesafe\config\1.2.1\f771f71fdae3df231bcd54d5ca2d57f0bf93f467\config-1.2.1.jar;C:\Users\Jire\.gradle\caches\modules-2\files-2.1\io.netty\netty-codec-http\4.1.5.Final\87bda1b9ec7e3f75ca721fc87735cbedad2aa1a\netty-codec-http-4.1.5.Final.jar;C:\Users\Jire\.gradle\caches\modules-2\files-2.1\io.netty\netty-handler\4.1.5.Final\6262900ee9487e62560030a136160df953b1cd6b\netty-handler-4.1.5.Final.jar;C:\Users\Jire\.gradle\caches\modules-2\files-2.1\com.googlecode.json-simple\json-simple\1.1.1\c9ad4a0850ab676c5c64461a05ca524cdfff59f1\json-simple-1.1.1.jar;C:\Users\Jire\.gradle\caches\modules-2\files-2.1\org.jetbrains.kotlinx\kotlinx-support-jdk7\0.3\3313e3973024cd6ca92c4b2a06fb3a7110743126\kotlinx-support-jdk7-0.3.jar;C:\Users\Jire\.gradle\caches\modules-2\files-2.1\ch.qos.logback\logback-core\1.1.2\2d23694879c2c12f125dac5076bdfd5d771cc4cb\logback-core-1.1.2.jar;C:\Users\Jire\.gradle\caches\modules-2\files-2.1\io.netty\netty-codec\4.1.5.Final\66bbf9324fa36467d041083f89328e2a24ec4f67\netty-codec-4.1.5.Final.jar;C:\Users\Jire\.gradle\caches\modules-2\files-2.1\io.netty\netty-buffer\4.1.5.Final\b5fb6bccda4d63d4a74c9faccdf32f77ab66abc1\netty-buffer-4.1.5.Final.jar;C:\Users\Jire\.gradle\caches\modules-2\files-2.1\io.netty\netty-transport\4.1.5.Final\37126b370722ff9631ee13c91139aacec0a71d1d\netty-transport-4.1.5.Final.jar;C:\Users\Jire\.gradle\caches\modules-2\files-2.1\junit\junit\4.10\e4f1766ce7404a08f45d859fb9c226fc9e41a861\junit-4.10.jar;C:\Users\Jire\.gradle\caches\modules-2\files-2.1\io.netty\netty-common\4.1.5.Final\607f8433d8782445e72abe34e43a7e57e86a5e6c\netty-common-4.1.5.Final.jar;C:\Users\Jire\.gradle\caches\modules-2\files-2.1\io.netty\netty-resolver\4.1.5.Final\5f367bedcdc185a727fda3296b9a18014cdc22c4\netty-resolver-4.1.5.Final.jar;C:\Users\Jire\.gradle\caches\modules-2\files-2.1\org.hamcrest\hamcrest-core\1.1\860340562250678d1a344907ac75754e259cdb14\hamcrest-core-1.1.jar;C:\Program Files (x86)\JetBrains\IntelliJ IDEA 2016.3\lib\idea_rt.jar" com.intellij.rt.execution.application.AppMain life.cheat.www.MainKt
19:50:56.518 [main] DEBUG i.n.u.i.l.InternalLoggerFactory - Using SLF4J as the default logging framework
19:50:56.526 [main] DEBUG i.n.c.MultithreadEventLoopGroup - -Dio.netty.eventLoopThreads: 8
19:50:56.543 [main] DEBUG i.n.util.internal.PlatformDependent0 - java.nio.Buffer.address: available
19:50:56.544 [main] DEBUG i.n.util.internal.PlatformDependent0 - sun.misc.Unsafe.theUnsafe: available
19:50:56.545 [main] DEBUG i.n.util.internal.PlatformDependent0 - sun.misc.Unsafe.copyMemory: available
19:50:56.545 [main] DEBUG i.n.util.internal.PlatformDependent0 - direct buffer constructor: available
19:50:56.546 [main] DEBUG i.n.util.internal.PlatformDependent0 - java.nio.Bits.unaligned: available, true
19:50:56.546 [main] DEBUG i.n.util.internal.PlatformDependent0 - java.nio.DirectByteBuffer.<init>(long, int): available
19:50:56.547 [main] DEBUG io.netty.util.internal.Cleaner0 - java.nio.ByteBuffer.cleaner(): available
19:50:56.547 [main] DEBUG i.n.util.internal.PlatformDependent - Platform: Windows
19:50:56.547 [main] DEBUG i.n.util.internal.PlatformDependent - Java version: 8
19:50:56.547 [main] DEBUG i.n.util.internal.PlatformDependent - -Dio.netty.noUnsafe: false
19:50:56.547 [main] DEBUG i.n.util.internal.PlatformDependent - sun.misc.Unsafe: available
19:50:56.548 [main] DEBUG i.n.util.internal.PlatformDependent - -Dio.netty.noJavassist: false
19:50:56.548 [main] DEBUG i.n.util.internal.PlatformDependent - Javassist: unavailable
19:50:56.548 [main] DEBUG i.n.util.internal.PlatformDependent - You don't have Javassist in your class path or you don't have enough permission to load dynamically generated classes.  Please check the configuration for better performance.
19:50:56.549 [main] DEBUG i.n.util.internal.PlatformDependent - -Dio.netty.tmpdir: C:\Users\Jire\AppData\Local\Temp (java.io.tmpdir)
19:50:56.549 [main] DEBUG i.n.util.internal.PlatformDependent - -Dio.netty.bitMode: 64 (sun.arch.data.model)
19:50:56.549 [main] DEBUG i.n.util.internal.PlatformDependent - -Dio.netty.noPreferDirect: false
19:50:56.549 [main] DEBUG i.n.util.internal.PlatformDependent - io.netty.maxDirectMemory: 3804758016 bytes
19:50:56.563 [main] DEBUG io.netty.channel.nio.NioEventLoop - -Dio.netty.noKeySetOptimization: false
19:50:56.563 [main] DEBUG io.netty.channel.nio.NioEventLoop - -Dio.netty.selectorAutoRebuildThreshold: 512
19:50:56.565 [main] DEBUG i.n.util.internal.PlatformDependent - org.jctools-core.MpscChunkedArrayQueue: available
19:50:56.712 [main] DEBUG i.n.buffer.PooledByteBufAllocator - -Dio.netty.allocator.numHeapArenas: 8
19:50:56.712 [main] DEBUG i.n.buffer.PooledByteBufAllocator - -Dio.netty.allocator.numDirectArenas: 8
19:50:56.712 [main] DEBUG i.n.buffer.PooledByteBufAllocator - -Dio.netty.allocator.pageSize: 8192
19:50:56.712 [main] DEBUG i.n.buffer.PooledByteBufAllocator - -Dio.netty.allocator.maxOrder: 11
19:50:56.712 [main] DEBUG i.n.buffer.PooledByteBufAllocator - -Dio.netty.allocator.chunkSize: 16777216
19:50:56.712 [main] DEBUG i.n.buffer.PooledByteBufAllocator - -Dio.netty.allocator.tinyCacheSize: 512
19:50:56.712 [main] DEBUG i.n.buffer.PooledByteBufAllocator - -Dio.netty.allocator.smallCacheSize: 256
19:50:56.712 [main] DEBUG i.n.buffer.PooledByteBufAllocator - -Dio.netty.allocator.normalCacheSize: 64
19:50:56.712 [main] DEBUG i.n.buffer.PooledByteBufAllocator - -Dio.netty.allocator.maxCachedBufferCapacity: 32768
19:50:56.712 [main] DEBUG i.n.buffer.PooledByteBufAllocator - -Dio.netty.allocator.cacheTrimInterval: 8192

Process finished with exit code 0

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.