Git Product home page Git Product logo

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

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

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

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

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: /

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.

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.

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

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

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]

ะกั‚ะฐั‚ะธั‡ะตัะบะธะต ั„ะฐะนะปั‹, ะผะตะดะปะตะฝะฝะฐั ั€ะฐะฑะพั‚ะฐ

ะพั‚ะดะฐะตั‚ ัั‚ะฐั‚ะธั‡ะตัะบะธะต ั„ะฐะนะปั‹ ะพั‡ะตะฝัŒ ะผะตะดะปะตะฝะฝะพ, ะธะปะธ ะฟั€ะพะธัั…ะพะดะธั‚ ะพั‚ะฒะฐะปะธะฒะฐะฝะธะต ะฟะพ ั‚ะฐะนะผะฐัƒั‚ัƒ.
ะกะพะฑะธั€ะฐะป ะธะท main ะธ pipeline ะฒะตั‚ะพะบ.
ะŸั€ะพะฒะตั€ััŽ ะฝะฐ embedded jetty.
ะะฐ windows 10 ะฟะฐั€ัƒ ั‚ั€ะพะนะบัƒ ั„ะฐะนะปะพะฒ ะฒั‹ะดะฐะตั‚ ั ะปะฐะณะฐะผะธ, ะฝะฐ Mac Os ะพะฑะปะพะผ).

ะฒะฐั€ะธะฐะฝั‚ ะฒั‹ะทะพะฒะฐ
server = embeddedJettyServer(9090) {
serveClasspathResources("/public")
}
ะธ
server = embeddedJettyServer(9090) {
serveFileSystem(File(fullpath+"/build/resources/main/public"))
}

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)

Documentation

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

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.

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

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

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

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

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 :) ?

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.

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/

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.

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

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)

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.

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

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

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.

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?

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.