Hello. using ktor on the server for the first time...
# ktor
c
Hello. using ktor on the server for the first time (im an android dev, so this is just a little side project). I generated a starter project from start.ktor.io , but now I want to deploy it so I'm trying to deploy onto railway.app when deploying I get an error of:
no main manifest attribute, in build/libs/ktor-starter-0.0.1.jar
Any tips for that? Have no idea what im doing. stackoverflow said to add a fat jar via a gradle task and that didn't work.
a
Are you able to run the fat JAR locally?
c
im able to run the starter project without even adding the fat jar.
but i also have no idea what im doing so maybe i totally missed the point of your question. lol
a
I mean after generating the fat JAR, are you able to run the application with the
java -jar ...
command?
c
yep. that works. i guess i gotta figure out a way to do that on railway. generate fatJar then run it
c
Just to confirm, are you generating the fat jar with the Ktor Gradle plugin, and running the actual fat jar? The lib to run should be named something like
ktor-starter-0.0.1-all.jar
(note the
-all
). The error shown looks like you’re trying to execute the normal jar, not the fat jar. The normal build process will create a jar file with the project name, but that one only includes your own project’s compiled code and resources. It cannot run on its own with the
java -jar
command, though it will able able to be executed through Gradle (
./gradlew run
). To run the app on Railway or other hosting services, you need to run the fat jar without Gradle, which bundles all dependences (Ktor, Netty, Serialization, etc.) along with your own code.
c
So what im telling railway.app to do now is as a build step,
gradle buildFatJar
and for deploy step,
gradle runFatJar
that seems to work, BUT gradle runFatJar won't run unless I have at least a gig of ram seemingly (even for hello world sample).
so i had to upgrade my plan
im also not sure if im using "Ktor Gradle plugin", im just using the plain vanilla hello world starter project
c
Yeah, that’s proabbly part of the problem. When you run it like that, you’re going to incur the memory penalty of Gradle along with the server application itself. Gradle is a beast and a memory hog, and you definitely don’t want to have that be part of the deployment
c
but since those *FatJar commands are there so im assuming im using the plugin?
c
The
buildFatJar
and
runFatJar
Gradle tasks are provided by the Ktor plugin, so yes it’s inlucded. Just wanted to make sure you were running those and not the typical
./gradlew assemble
c
Yeah, that’s proabbly part of the problem. When you run it like that, you’re going to incur the memory penalty of Gradle along with the server application itself. Gradle is a beast and a memory hog, and you definitely don’t want to have that be part of the deployment
oh really? what would you suggest then (apologies. i literally have 0 exp on server)
c
The start command should be a something like
java -jar build/libs/ktor-starter-0.0.1-all.jar
. This does not use Gradle, but executes the fat jar directly, similar to running a
.exe
on Windows
c
thinking out loud. i wonder if i can just limit gradle to run at like 100MB or something
c
You don’t want Gradle running in prod at all
🤯 1
c
oh interesting. so just run the jar directly.
but how do i generate the jar? am i good to run
gradle buildFatJar
? i guess not based on your last message
or is your suggestion that i should be pushing a prebuilt jar to railway, and then just execute that?
c
I haven’t used Railway specifically, but it doesn’t look too different from most CI/hosting platforms, so here’s an overview of the general process: 1. On a build server, your application code will be “built”. This is the “build command” you provide, and the expected output is a “build artifact”. For Java-based applications, this is typically a single file, that is the fat jar of your application and all its dependencies. Build servers often have higher memory and CPU limits, because they don’t run forever, but instead complete in just a few minutes and are then shut down. This command should be
./gradlew buildFatJar
. 2. The build server uploads the build artifact to another server, and then runs the “start command” there. These servers can often be run with fairly minimal memory and CPU, because the idle server application typically doesn’t consume too much system resources. Memory and CPU usage scales with incoming traffic, not really with the application code. Because of the memory limitations, and because these servers are exposed to the public internet, you don’t want to expose yourself to anything more than is absolutely necessary. Thus, you should execute the build artifact generated in step 1, and not run a Gradle build command. So the run command should be
java -jar build/libs/ktor-starter-0.0.1-all.jar
.
😍 1
c
wow okay cool. TIL. I gotta see what railway wants me to do because it seems like they like to build the application and run it.
thanks. i reached out to there support. they seem to be pretty adament that calling gradle buildFatJar is fine. But moving from runFatJar to just
java -jar myjar.jar
seemed to fix my out of memory issues when simply trying to deploy