Only show guides for your app
The Java app runs one fat jar — your build tool makes it. How to choose between Maven and Gradle, with a minimal, complete fat-jar config for each that produces a ready-to-run app.jar.
The Java application has one job: it runs a single runnable jar. Nothing compiles on the server, so your build tool does the real work — packaging your code and every library it uses into one fat jar you upload. The two tools for that are Maven and Gradle. This guide helps you pick one and gives a minimal, complete config for each that produces a app.jar ready to run on Falix.
| At a glance | |
|---|---|
| You need | A Falix server running the Java application; Maven or Gradle on your own computer |
| Plan | Any |
| Time | Twenty minutes |
| Good to already know | Java on Falix (the fat-jar model, the JAR FILE variable) |
Both produce exactly the same thing — a runnable fat jar — so there's no wrong answer. Pick by fit:
| Maven | Gradle | |
|---|---|---|
| Config file | pom.xml (XML) |
build.gradle (Groovy) or build.gradle.kts (Kotlin) |
| Style | Convention-heavy, verbose, predictable | Concise, scriptable, flexible |
| Learning curve | Gentle; easy to read and copy | Steeper, but less boilerplate once learned |
| Fat-jar plugin | Shade | Shadow |
| Best when | You want the simplest, most-documented path, or your project/tutorial already uses it | You want faster incremental builds, a terser config, or the project already uses it |
Rule of thumb: if you're starting from scratch and just want it to work, Maven has the shortest path and the most copy-paste examples. If you value a compact build script and quicker rebuilds — or your tutorial/framework leans that way — Gradle is a fine choice. If a project already has one, keep it; converting buys you nothing.
Whichever you use, the output must be a jar that:
app.jar (to match the JAR FILE variable's default), andMain-Class in its manifest, andTest it locally first — java -jar app.jar should start your program on your own machine. If it runs there, it runs on Falix.
pom.xmlThe Shade plugin bundles dependencies and writes the Main-Class into the manifest. This complete pom.xml produces target/app.jar:
<project xmlns="http://maven.apache.org/POM/4.0.0">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>demo</artifactId>
<version>1.0.0</version>
<packaging>jar</packaging>
<properties>
<maven.compiler.release>21</maven.compiler.release>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<!-- your libraries go here -->
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.11.0</version>
</dependency>
</dependencies>
<build>
<finalName>app</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.6.0</version>
<executions>
<execution>
<phase>package</phase>
<goals><goal>shade</goal></goals>
<configuration>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>app.Main</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Build with mvn package. <finalName>app</finalName> makes the output target/app.jar, and the ManifestResourceTransformer sets Main-Class to your class (app.Main — change it to yours). Maven also leaves a target/original-app.jar next to it — that's the thin pre-shade jar; upload the plain app.jar, not that one.
build.gradleGradle's fat-jar plugin is Shadow. With the application plugin providing the main class, the Shadow plugin writes it into the manifest for you. This complete build.gradle produces build/libs/app.jar:
plugins {
id 'application'
id 'com.gradleup.shadow' version '8.3.5'
}
group = 'com.example'
version = '1.0.0'
repositories {
mavenCentral()
}
dependencies {
// your libraries go here
implementation 'com.google.code.gson:gson:2.11.0'
}
java {
toolchain { languageVersion = JavaLanguageVersion.of(21) }
}
application {
mainClass = 'app.Main'
}
tasks.named('shadowJar') {
archiveFileName = 'app.jar'
}
Build with gradle shadowJar. archiveFileName = 'app.jar' names the output build/libs/app.jar, and mainClass feeds the manifest. Change app.Main to your class.
🎯 Good to know: Set the compiler/toolchain version (
maven.compiler.releaseor Gradle'slanguageVersion) to a Java version no newer than the runtime you'll pick in Settings. A jar built for Java 21 won't run on a Java 17 runtime — that mismatch is the most common Java startup failure. See Java on Falix.
Same two paths as any Java project:
app.jar into the File Manager, or copy it up over SFTP, then Start.mvn package or gradle shadowJar) plus one to move the jar into place. See Build steps.no main manifest attribute, in app.jar — the manifest has no Main-Class. You built a plain jar; make sure the Shade transformer / Gradle mainClass is set and you're uploading the shaded jar.NoClassDefFoundError / ClassNotFoundException — a dependency isn't inside the jar. The fat-jar step didn't run or you uploaded the thin jar (original-app.jar on Maven). Rebuild and upload the bundled one.UnsupportedClassVersionError — the Settings runtime is older than the JDK you compiled with. Bump the Java version in Settings, or lower your build's target.The build tools themselves go far deeper — the official references are maven.apache.org and gradle.org.