Ktor - post unhanldled error with coroutines - kotlin

I a new to Kotlin and Ktor in particular, so I have tried to do simple post request. As you can see below, there is nothing special.
routing {
post("/articles/add"){
val post = call.receive<ArticleRequest>()
println(post)
}
Error shown in logs is below and I don't understand why I should use here coroutines.
ERROR Application - Unhandled: POST - /articles/add
java.lang.IllegalStateException: Using blocking primitives on this dispatcher is not allowed. Consider using async channel instead or use blocking primitives in withContext(Dispatchers.IO) instead.
I am using 1.4.2 version. I would appreciate any help.

If you are using Jackson this is a bug and there is a suggested workaround:
routing {
post("/articles/add") {
with(Dispatchers.IO) {
val post = call.receive<ArticleRequest>()
println(post)
}
}
}
Or you can rollback to 1.4.1 until the bug is solved.

I've experienced the same issue after upgrading to ktor 1.4.2 and Kotlin 1.4.20, and I used both Moshi and Gson on this specific project but I don't believe they are causing this issue.
If you have a 'gradle.properties' file, add these ( or whatever version you wish to use ) :
ktor_version=1.3.2
kotlin_version=1.3.70.
Otherwise, in your 'build.gradle' file, create variables for different version :
buildscript {
ext.kotlin_version = '1.3.70'
ext.ktor_version = '1.3.2'
repositories {
jcenter()
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
Then sync your gradle, run project.. all should be good.
However if you still experience some gradle-related issue, try this :
go to gradle (folder) -> wrapper -> open gradle_wrapper.properties and make sure the url has version 6.x.x or 5.x.x.
Mine looks like this currently:
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.6.1-all.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

Related

How to add SolanaKT to my project kotlin?

I have an existing kotlin project. Now I'm trying to add the SolanaKT library to it.
I have added the JitPack repository maven { url 'https://jitpack.io' } and dependency implementation 'com.github.metaplex-foundation:SolanaKT:2.0.1'.
Then I did a gradle sync.
I try using:
val endPoint = RPCEndpoint.devnetSolana
val network = HttpNetworkingRouter(endPoint)
val solana = Solana(network)
But i get error Unresolved reference: RPCEndpoint.
What am I doing wrong? Is there anything else I should do (maybe copy some files to the project) ?

Why do I need to reference a custom gradle config with square brackets?

I created a gradle build config just to download some dependencies. The documentation has been sparse, so I've piece together this working snippet based on random snippets and guesses.
configurations {
create("downloadDeps")
}
dependencies {
// JSON
configurations["downloadDeps"]("com.fasterxml.jackson.core:jackson-databind:2.13.3")
configurations["downloadDeps"]("com.fasterxml.jackson.module:jackson-module-kotlin:2.13.3")
}
repositories {
// internal repository
maven {
url = uri("...")
credentials {
username = System.getenv("ARTIFACTORY_USER") ?: System.getProperty("ARTIFACTORY_USER") as String
password = System.getenv("ARTIFACTORY_TOKEN") ?: System.getProperty("ARTIFACTORY_TOKEN") as String
}
}
}
tasks.register<Copy> ("downloadDeps") {
from(configurations["downloadDeps"])
into("lib/")
}
If I reference the "downloadDeps" dependency like configuration.downloadDeps or downloadDeps("com.fasterxml.jackson.core:jackson-databind:2.13.3"). I get an error about an unresolved reference to "downloadDeps".
Why does implementation("...") or configuration.implementation.get() work?
The documentation #Slaw provided helped me understand why I can do something like this:
implementation("group:artifact:1.0.0")
but not
myCustomConfig("group:artifact:1.0.0")
implementation being declared that way is supported because it comes from a plugin (the Kotlin/Java plugins)
The simplest way to associate a dependency with myCustomConfig would be to do this (see these docs):
"myCustomConfig"("group:artifact:1.0.0")

Ktor client NoSuchMethodError

I want to write a telegram bot and use this library from Github for that. In this telegram bot I need to make some requests to another service, so I want to use the ktor client library for that. However when I try to instantiate the ktor httpClient I get the following exception:
Exception in thread "main" java.lang.NoSuchMethodError: 'void io.ktor.util.collections.ConcurrentMap.<init>(io.ktor.util.Lock, int, int, kotlin.jvm.internal.DefaultConstructorMarker)'
at io.ktor.client.engine.cio.CIOEngine.<init>(CIOEngine.kt:32)
at io.ktor.client.engine.cio.CIO.create(CIOCommon.kt:23)
at io.ktor.client.HttpClientKt.HttpClient(HttpClient.kt:42)
at io.ktor.client.HttpClientJvmKt.HttpClient(HttpClientJvm.kt:21)
at io.ktor.client.HttpClientJvmKt.HttpClient$default(HttpClientJvm.kt)
at problem.ktor.MainKt.main(Main.kt:9)
at problem.ktor.MainKt.main(Main.kt)
I made a new project and narrowed the problem down to the telegram bot library, which apparently conflicts with the kotr library. I assume some version conflict of the kotr library, because that's where the exception happens. How can I solve the conflict?
Here is a minimal reproducible example. Use the following build.gradle.kts file:
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins {
application
kotlin("jvm") version "1.4.30"
}
repositories {
mavenCentral()
maven(url = "https://jitpack.io")
}
dependencies {
implementation("io.ktor:ktor-client-core:1.5.2")
implementation("io.ktor:ktor-client-cio:1.5.2")
implementation("com.github.kotlin-telegram-bot:kotlin-telegram-bot:6.0.4")
}
And run the following minimal main function:
import io.ktor.client.*
fun main() {
HttpClient()
}
Maybe it's important, I use Java 15.0.2.
The problematic dependency is com.github.kotlin-telegram-bot.kotlin-telegram-bot:webhook:6.0.4. As a workaround you can exclude it since it's just a sample:
implementation("com.github.kotlin-telegram-bot:kotlin-telegram-bot:6.0.4") {
exclude(module = "webhook")
}

Strange exception thrown in Ktor

Today i encountered a strange status page exception being thrown in Ktor.
I am trying to build a simple api with ktor and i did this Route:
fun Route.phrase(db : Repository){
post(PHRASE_ENDPOINT){
val request = call.receive<Request>()
val phrase = db.add(EmojiPhrase(request.toString(), request.toString()))
this.call.respond(phrase)
}}
when i try to send the request i get
java.lang.ClassNotFoundException: kotlinx.coroutines.io.ByteReadChannel
has anyone encountered this problem
im using :
ktor_version=1.3.2,
kotlin_version=1.4.10,
moshi_version= 1.0.1
Issue appears to be in moshi converter: https://github.com/rharter/ktor-moshi/issues/7#issuecomment-580977097
Until the PR is merged, you can use the patched version through
jitpack
buildscript {
repositories {
jcenter()
maven { url 'https://jitpack.io' }
}
}
dependencies {
implementation 'com.github.cs125-illinois:ktor-moshi:7252ca49ed'
}

java.lang.UnsupportedOperationException: Packages and file facades are not yet supported in Kotlin reflection

When starting a basic Ktor app, I get:
Exception in thread "main" java.lang.UnsupportedOperationException: Packages and file facades are not yet supported in Kotlin reflection. Meanwhile please use Java reflection to inspect this class: class com.example.ApplicationKt
at kotlin.reflect.jvm.internal.KClassImpl.reportUnresolvedClass(KClassImpl.kt:301)
at kotlin.reflect.jvm.internal.KClassImpl.access$reportUnresolvedClass(KClassImpl.kt:43)
at kotlin.reflect.jvm.internal.KClassImpl$Data$descriptor$2.invoke(KClassImpl.kt:53)
at kotlin.reflect.jvm.internal.KClassImpl$Data$descriptor$2.invoke(KClassImpl.kt:44)
at kotlin.reflect.jvm.internal.ReflectProperties$LazySoftVal.invoke(ReflectProperties.java:92)
at kotlin.reflect.jvm.internal.ReflectProperties$Val.getValue(ReflectProperties.java:31)
at kotlin.reflect.jvm.internal.KClassImpl$Data.getDescriptor(KClassImpl.kt)
at kotlin.reflect.jvm.internal.KClassImpl$Data$objectInstance$2.invoke(KClassImpl.kt:106)
at kotlin.reflect.jvm.internal.ReflectProperties$LazyVal.invoke(ReflectProperties.java:62)
at kotlin.reflect.jvm.internal.ReflectProperties$Val.getValue(ReflectProperties.java:31)
at kotlin.reflect.jvm.internal.KClassImpl$Data.getObjectInstance(KClassImpl.kt)
at kotlin.reflect.jvm.internal.KClassImpl.getObjectInstance(KClassImpl.kt:239)
at io.ktor.server.engine.ApplicationEngineEnvironmentReloading.createModuleContainer(ApplicationEngineEnvironmentReloading.kt:328)
at io.ktor.server.engine.ApplicationEngineEnvironmentReloading.executeModuleFunction(ApplicationEngineEnvironmentReloading.kt:317)
at io.ktor.server.engine.ApplicationEngineEnvironmentReloading.instantiateAndConfigureApplication(ApplicationEngineEnvironmentReloading.kt:275)
at io.ktor.server.engine.ApplicationEngineEnvironmentReloading.createApplication(ApplicationEngineEnvironmentReloading.kt:127)
at io.ktor.server.engine.ApplicationEngineEnvironmentReloading.start(ApplicationEngineEnvironmentReloading.kt:247)
at io.ktor.server.netty.NettyApplicationEngine.start(NettyApplicationEngine.kt:106)
at io.ktor.server.netty.NettyApplicationEngine.start(NettyApplicationEngine.kt:18)
at io.ktor.server.engine.ApplicationEngine$DefaultImpls.start$default(ApplicationEngine.kt:52)
at io.ktor.server.netty.EngineMain.main(EngineMain.kt:17)
at com.example.ApplicationKt.main(Application.kt:10)
The app is just:
fun main(args: Array<String>): Unit = EngineMain.main(args)
fun Application.demoModule() {
routing {
get("/") {
call.respondText("Hello ${call.parameters["name"]}")
}
}
}
I just noticed the file resources.application.conf had an issue.
It had the wrong module name. I changed com.example.ApplicationKt.module to com.example.ApplicationKt.demoModule:
ktor {
deployment {
port = 8080
port = ${?PORT}
}
application {
modules = [ com.example.ApplicationKt.demoModule ]
}
}
What's annoying is that the error help says nothing about it.