Manifest Reference

Every field in kwenza.toml, and the kwenza.lock format it produces. For a narrative walkthrough instead, see Getting Started.

[package]

Field Required? Meaning

name

Yes

The artifact’s name. Used to name the packaged jar: <output-dir>/<name>-<version>.jar.

group

Yes

The Maven group ID, e.g. com.example. Combined with name and version for the project’s own identity (not used for dependency resolution, which is per-dependency — see below).

version

Yes

The project’s version, e.g. 0.1.0. Any string is accepted; kwenza doesn’t currently enforce semver.

java-version

No — defaults to "21"

Passed straight to javac --release. kwenza checks this against the JDK actually running it before compiling — see JDK compatibility checking.

main-class

No — required only for kwenza run and for a runnable kwenza package jar

Fully-qualified class name with a public static void main(String[]). Written to the packaged jar’s Main-Class manifest attribute.

output-dir

No — defaults to "target"

Where build output goes (<output-dir>/classes, <output-dir>/<name>-<version>.jar). Override if you’d rather match Gradle’s build, or anything else.

[package]
name = "my-app"
group = "com.example"
version = "0.1.0"
java-version = "21"               # optional
main-class = "com.example.Main"   # optional, required for `run`
output-dir = "target"             # optional

JDK compatibility checking

javac --release N can never target a release newer than the JDK actually running it. kwenza checks this itself before compiling and fails fast with a specific message (kwenza is running on JDK 21, but [package] java-version = "25" requires JDK 25 or newer…​) rather than letting a cryptic javac error surface. The running JDK can be newer than java-version — that’s the normal case, not an error.

[dependencies] and [dev-dependencies]

Each entry maps an alias to a Maven coordinate:

[dependencies]
guava = { module = "com.google.guava:guava", version = "33.2.1-jre" }

[dev-dependencies]
junit-console = { module = "org.junit.platform:junit-platform-console-standalone", version = "6.1.3" }
mockito = { module = "org.mockito:mockito-core", version = "5.23.0" }
Key Meaning

(the table key, e.g. guava)

A local alias — currently just a label; it doesn’t yet affect classpath ordering or generated accessors.

module

"group:artifact" — exactly two segments, colon-separated.

version

Either an exact version string, or { ref = "alias" } pointing into [versions]. kwenza doesn’t currently support version ranges ([1.0,2.0)-style Maven ranges) or LATEST/RELEASE — pin an exact version either way.

This is deliberately the same shape as Gradle’s libs.versions.toml version catalogs (module = "group:artifact", version.ref included) — the notation Java developers already know, rather than inventing new syntax.

[dependencies] vs [dev-dependencies] mirrors Cargo, replacing Maven’s <scope>test</scope>: dev-dependencies are resolved and put on the test-only classpath (kwenza test), never on the main/run/package classpath, and never leak into a consumer’s transitive graph the way a compile/default-scope Maven dependency would.

kwenza test specifically needs org.junit.platform:junit-platform-console-standalone (or another dependency providing the same org.junit.platform.console.ConsoleLauncher class) as a dev-dependency — plain org.junit.jupiter:junit-jupiter isn’t enough on its own, since that artifact has the JUnit 5 API and engine but not the console launcher. Anything else you add as a dev-dependency (Mockito above, AssertJ, …​) needs no kwenza-side support at all — it’s just another jar on the test classpath. See kwenza test for how it’s actually invoked.

[versions]

An optional table of shared version strings, referenced from [dependencies]/[dev-dependencies] with version.ref instead of repeating the literal version everywhere:

[versions]
guava = "33.2.1-jre"

[dependencies]
guava = { module = "com.google.guava:guava", version.ref = "guava" }

version.ref = "guava" is TOML dotted-key shorthand for version = { ref = "guava" } — both forms parse identically. Useful for keeping related artifacts (e.g. several modules from the same project) pinned to one version in one place. A version.ref pointing at a key that doesn’t exist in [versions] is a manifest error, reported before any resolution is attempted. Like plain version strings, [versions] entries must be exact versions, not ranges.

kwenza.lock

Written by dependency resolution, read by every subsequent build/run/package/test unless it’s stale (the declared dependencies changed). Safe to commit — that’s the point (see Architecture for the reproducibility model).

manifest-hash = "fcd7b2cea55e61ce18d4af7feecbc79f9e100e5c256c0e7784bc54dcb6427ee4"

[[resolved]]
module = "com.google.guava:guava"
version = "33.2.1-jre"
sha256 = "452b2d9787b7d366fa8cf5ed9a1c40404542d05effa7a598da03bbbbb76d9f31"
requested-by = ["direct"]

[[resolved]]
module = "com.google.guava:failureaccess"
version = "1.0.2"
sha256 = "8a8f81cf9b359e3f6dfa691a1e776985c061ef2f223c9b2c80753e1b458e8064"
requested-by = ["com.google.guava:guava"]
Field Meaning

manifest-hash (top-level)

A hash of every declared dependency (both tables). If this doesn’t match the current kwenza.toml, the lock is considered stale and a full re-resolution runs automatically — no separate "lockfile out of date" error to chase down.

module

The resolved artifact’s group:artifact.

version

The exact version that won mediation for this module (see Architecture for how conflicts are resolved).

sha256

A checksum of the downloaded jar, computed by kwenza itself — independent of (and in addition to) the .sha1 Maven Central already publishes, which is verified at download time regardless of the lockfile. Every build that uses the lock checks each jar against this value, including jars already in the local cache, and fails with the offending jar’s path if one doesn’t match: delete that jar and kwenza re-downloads and re-verifies it.

requested-by

Which module(s) pulled this one in transitively, or ["direct"] if it’s declared directly in kwenza.toml. Diagnostic only — not consumed by kwenza itself (yet — see the deferred kwenza tree command in AGENTS.md).