Application
An [application] project compiles sources, runs tests, packages a JAR with an embedded classpath manifest, and optionally builds a Docker image or a GraalVM native binary.
Minimal configuration
[application] name = "my-app" version = "1.0.0"
mainClass is optional. Curie scans the compiled bytecode for a class with a public static void main(String[]) method and uses it automatically. Declare it explicitly when there is more than one candidate:
[application] name = "my-app" version = "1.0.0" mainClass = "com.example.Main" # explicit override groupId = "com.example" # required for curie publish
Build output
Building my-app v1.0.0 Resolve deps 3 JAR(s) Compile 4 source file(s) Tests ✔ 12 tests successful Package my-app-1.0.0.jar Done target/my-app-1.0.0.jar
The JAR includes a MANIFEST.MF with Main-Class and a Class-Path entry pointing to the dep JARs in target/libs/. Run it with:
Running my-app v1.0.0
Hello from my-app.
Full configuration reference
[application] name = "my-app" version = "1.0.0" mainClass = "com.example.Main" # optional — auto-detected if omitted groupId = "com.example" # required for curie publish # Java version for javac --release (optional — omit to target the running JDK) [java] releaseVersion = "25" # JUnit Platform Console Standalone version (workspace-inheritable) [test] junitPlatformVersion = "6.0.3" # kotlinc + kotlin-stdlib (only needed when .kt sources are present) [kotlin] version = "2.1.21" # Production dependencies [dependencies] "com.fasterxml.jackson.core:jackson-databind" = "2.17.2" "com.google.guava:guava" = "" # version from BOM # Test-only dependencies [test-dependencies] "org.assertj:assertj-core" = "3.26.0" # BOMs to import for version management [bom-imports] "com.google.guava:guava-bom" = "33.4.8-jre" [test-bom-imports] "org.junit:junit-bom" = "5.11.0" # Annotation processors run during compilation [annotation-processors] "org.projectlombok:lombok" = "1.18.32" [test-annotation-processors] "com.example:test-proc" = "1.0.0" # Additional Maven repositories (Maven Central is always included) [[repositories]] id = "my-nexus" url = "https://nexus.example.com/repository/releases/" # Docker image — enabled by this section or by a Dockerfile at project root [docker] baseImage = "eclipse-temurin:21-jre-alpine" # default imageName = "my-app" # default: application.name imageTag = "latest" # default: application.version # GraalVM native-image compilation [native-image] outputName = "my-app" # default: application.name configDir = "src/main/resources/META-INF/native-image" extraArgs = ["--no-fallback"] # Build-info — git commit id embedded in the JAR (enabled by default) [build-info] enabled = false # Publishing to a Maven repository [publish] repository = "my-nexus" sign = true description = "My application" homepage = "https://github.com/example/my-app" licenses = ["Apache-2.0"] developers = [{ id = "alice", name = "Alice", email = "alice@example.com" }]
Key fields
| Field | Required | Default | Notes |
|---|---|---|---|
name | Yes | — | Used as the JAR base name and Docker image name |
version | Yes | — | Embedded in JAR name and MANIFEST.MF |
mainClass | No | Auto-detected | Must be set explicitly when multiple main classes exist |
groupId | No | — | Required for curie publish and SBOM metadata.component |
mainClass auto-detection
When mainClass is omitted, Curie scans compiled .class files for a public static void main(String[]) method. If exactly one is found, it is used. If zero or more than one are found, the build fails with a message listing the candidates — set mainClass explicitly to resolve the ambiguity.
Java 21+ "instance main methods" (a class with a void main() instance method, no static, no String[]) are also detected. See examples/simplified-main.
Source layouts
Curie supports two layouts, and they can coexist in the same project:
- Flat-package —
src/com.example/Main.java(dot-delimited package as directory name) - Maven —
src/main/java/com/example/Main.java
Test files (*Test.java, *Tests.java, *Spec.java) co-located in the source tree are treated as tests; a separate tests/ or src/test/java/ directory is optional for integration tests.
build-info
When the project is inside a git repository, Curie automatically embeds META-INF/build-info.properties in the JAR:
git.commit.id=a3f1b2c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0
If there are uncommitted changes the value is suffixed with -dirty. Set [build-info] enabled = false to opt out.