Docs · Running your bot

Java bots: JDA and runnable jars

All docs

Java servers run a jar. There is no build step on the server: you build the bot on your computer (or in GitHub Actions) into one jar that includes its dependencies, and the server runs java -jar on it.

Versions

Java 17, 21 and 25, chosen at checkout or under Startup, Docker Image. Java 21 is the default. Pick at least the version your jar was built for; newer is fine.

Build a runnable jar

A normal jar task leaves JDA and your other libraries out, and the bot stops with NoClassDefFoundError. Build a jar with dependencies included:

Gradle

plugins {
    id 'java'
    id 'application'
    id 'com.gradleup.shadow' version '8.3.5'
}

application {
    mainClass = 'com.example.bot.Main'
}

Then ./gradlew shadowJar, and upload build/libs/yourbot-1.0-all.jar.

Maven

Add the maven-assembly-plugin with the jar-with-dependencies descriptor and your main class in its manifest, run mvn package, and upload target/yourbot-1.0-jar-with-dependencies.jar.

Upload and run it

  1. Upload the jar in Files, or over SFTP.
  2. Leave Bot file empty if it is the only jar: it is found in the top folder, build/libs or target. With several, set it to the right one.
  3. Restart. The console shows Starting: java -jar yourbot-1.0-all.jar, then your bot's output.

Git deploy pulls files but does not build Java. To deploy from GitHub, have a GitHub Actions workflow build the jar and commit it to a branch the server follows, or upload the jar by hand.

The token

String token = System.getenv("BOT_TOKEN");
JDA jda = JDABuilder.createDefault(token).build();

Some ready-made bots ask for their token in the console instead (JMusicBot does on its first start). Type it into the box at the bottom of the Console page; what you type there goes to the program's input.

Memory

The heap may use three quarters of your plan's memory (768 MB on Flurry); on its own, Java would only take a quarter. If the bot stops with java.lang.OutOfMemoryError, something is holding on to too much, or the bot needs a bigger plan. JDA's member and message caches are the usual suspects: turn off the cache flags and intents you do not use.

Stopping cleanly

Stop sends the program an interrupt, which runs Java's shutdown hooks. To let JDA close its connection to Discord properly, add one:

Runtime.getRuntime().addShutdownHook(new Thread(jda::shutdown));

When the jar will not start

  • UnsupportedClassVersionError ... compiled by a more recent version: pick a newer Java under Startup.
  • no main manifest attribute: the jar does not say which class to start. Set mainClass as above and rebuild.
  • NoClassDefFoundError: net/dv8tion/jda/...: the jar was built without its dependencies. Use shadowJar or jar-with-dependencies.
  • InvalidTokenException: the token is wrong or BOT_TOKEN is empty. Paste it into Startup and restart.

The console adds a [SnowServers] Hint: line for each of these.

Something here wrong or out of date? Tell us and it gets fixed.