heroku deploy issue says ktor env - kotlin

i got the same problem every time i try to deploy to heruko
https://prnt.sc/IeH3wooTqqAj
a screenshot from the terminal
1- https://prnt.sc/fqpj3f2lQTz8
2- https://prnt.sc/-710l_bznc2B
this is my application.kt
fun main() {
embeddedServer(Netty, port = 8087, host = "0.0.0.0") {
module {
module()
}
}.start(wait = true)
}
Suppress("unused")
fun Application.module() {
configureKoin()
configureAuth()
configureRouting()
configureSerialization()
configureMonitoring()
configureSession()
}
Prockfile
web: build/install/com.example.googleauth/bin/com.example.googleauth
worker: python scheduler.py
every thing is uptodate and i also add the Config Vars on heroku setting
i also tryed the embedded way and also the engin way same issue

Related

Unable to perform get request in ktor framework

I am new to ktor and trying to create api in it.As I have downloaded project from ktor.io and opened it inside IntelliJ idea community edition then run button is showing disabled and when I am running it on right clicking on application.kt file and clicking on run application option.Its showing:
ktor.application - Responding at http://0.0.0.0:8080
When I am going to this link on webpage it is showing:
The web page at http://0.0.0.0:8080/ might be temporarily down or it may have moved permanently to a new web address.
Even if I have get route defined below is my code:
Application.kt
fun main() {
embeddedServer(Netty, port = 8080, host = "0.0.0.0") {
configureRouting()
}.start(wait = true)
}
Routing.kt
fun Application.configureRouting() {
// Starting point for a Ktor app:
routing {
get("/") {
call.respondText("Hello World!")
}
}
}
Someone let me know What is an issue and how can I resolve it.

MongoDB Database is not created in Kotlin(Ktor)

please i need help with connecting a mongodb to my ktor application.
This is the code i have, as followed from this article: https://himanshoe.com/mongodb-in-ktor
class MongoDataHandler {
val client = KMongo.createClient().coroutine
val database = client.getDatabase("dev")
val userCollection = database.getCollection<User>()
suspend fun adduser(email: String, username: String, password: String): User? {
userCollection.insertOne(User(userId = null, email = email, userName = username, passwordHash = password))
return userCollection.findOne(User::email eq email )
}
suspend fun finduser(id: String): User?{
return userCollection.findOneById(id)
}
}
I installed mongodb as directed from their website. The mongodb is started as a service upon successful install. I run this command "C:\Program Files\MongoDB\Server\5.0\bin\mongo.exe" to use the mongodb. When i check for the available database using "show dbs", i realize that my database(dev) is not listed.
This is the dependency am using:
implementation("org.litote.kmongo:kmongo-coroutine:4.2.8")
And this the the error i am getting:
[eventLoopGroupProxy-4-1] INFO Application - 500 Internal Server Error:
POST - /user
I guess i am doing something wrong... thanks in advance
Try to change your MongoDataHandler to the following, using the MongoClients.create() method, and adding a codecRegistry to your client.
You will not need the connection string settings if you are using the local connection with the default settings:
class MongoDataHandler {
private val database: MongoDatabase
private val usersCollection: MongoCollection<User>
init {
val pojoCodecRegistry: CodecRegistry = fromProviders(
PojoCodecProvider.builder()
.automatic(true)
.build()
)
val codecRegistry = fromRegistries(MongoClientSettings.getDefaultCodecRegistry(), pojoCodecRegistry)
val settings: MongoClientSettings = MongoClientSettings.builder()
// .applyConnectionString("localhost") => add the connection string if not using localhost
.codecRegistry(codecRegistry)
.build()
val mongoClient = MongoClients.create(settings)
database = mongoClient.getDatabase("dev")
usersCollection = database.getCollection(User::class.java.name, User::class.java)
}
Also, if you are not using docker, try to use docker-compose to orchestrate your mongodb container:
version: '3'
services:
mongo:
image: mongo:latest
ports:
- "27017:27017"
If you want a running example with Ktor/MongoDB take a look in this project
I assume you are in development mode and trying this in our local machine.
Make sure you have MongoDB installed on the local machine and the local server is running well. Here is a guide for ubuntu.
After successful setup and installation of MongoDB, run this command
mongo --eval 'db.runCommand({ connectionStatus: 1 })'
The output should contain a line as below:
connecting to : mongodb://127.0.0.1:27017/?compressors=disabled&gssapiServiceName=mongodb
Make sure to add this line while creating client in the ConnectionString like:\
private val client = KMongo.createClient(
ConnectionString("mongodb://127.0.0.1:27017")
).coroutine
Then try working on your requests/operations with the Ktor, it should work fine.

How to Run Ktor Embedded Server from Code

I've written a simple Ktor server that processes a JSON payload from an incoming POST request. Now, I want to spawn this server from another application, and after processing the request, shut it down.
So the first problem I need to solve is: how do I spawn the Ktor server from some other 'driver' Kotlin code? All the tutorials I've found online are 1-2 years old, and are apparently using an older version of Ktor, where the main class looks like this:
fun main(args: Array<String>) {
embeddedServer(Netty, 8080) {
routing {
get("/") {
call.respondText("Hello from Kotlin Backend", ContentType.Text.Html)
}
}
}.start(wait = true)
}
It's easy to see that one can just run the embeddedServer(Netty, 8080) { ... }.start(wait = true) from wherever they want, to spawn the server. But I downloaded the Ktor plugin for IntelliJ IDEA yesterday, and it seems things have changed lately. This is what the new main class looks like:
fun main(args: Array<String>): Unit = io.ktor.server.netty.EngineMain.main(args)
#Suppress("unused") // Referenced in application.conf
#kotlin.jvm.JvmOverloads
fun Application.module(testing: Boolean = false) {
install(ContentNegotiation) {
gson {
}
}
routing {
get("/") {
call.respondText("HELLO WORLD!", contentType = ContentType.Text.Plain)
}
get("/json/gson") {
call.respond(mapOf("hello" to "world"))
}
}
}
Now, the Application.module(...) function takes care of setting up the routing and stuff, while the actual running of the server is done internally by io.ktor.server.netty.EngineMain.main(args). Also, properties like the port number are referenced from the application.conf file, and I'm not quite sure how it figures out where to find that application.conf file.
I have been able to run this Ktor server using gradlew. I also understand that it is possible to export it as an executable jar and run it (as explained here). But I can't find out how to run it from code. Any suggestions?
Edit: And it would be nice if I could set the port number from the driver code.

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.

Ktor Netty Server sending an empty response

I'm using ktor 0.9.5. I'm trying a simple example. But when a try to connect to the server i get ERR_EMPTY_RESPONSE. This is my code.
fun main(args: Array<String>) {
embeddedServer(Netty, port = 8080, host = "localhost") {
install(DefaultHeaders)
install(CallLogging)
routing {
get(path = "/") {
call.respondText("Hello World!!")
}
}
}.start()
}
Doing some research I found that changing the project to Maven fix the problem, but because of rules of my organization I can't do it. Any other solution... Thanks before hand.
I have added a println("sometext") before call.respondText("Hello World!!") and it's never executed.
With ERR_EMPTY_RESPONSE error, I guess you are requesting the server from a Google Chrome browser. Right ?
Are you trying to connect to the server from another computer? If so it won't work because you have set the server to only respond for requests coming from localhost.
embeddedServer(Netty, port = 8080, host = "localhost")
Even if you add a println() it won't execute.
Try to remove host = "localhost" from embeddedServer() parameters an re-test.