What naming rules govern catalog aliases in the TOML, and what common errors do invalid names cause?
answer
- -, _, . all map to dot in accessor
- commons-lang3 -> libs.commons.lang3
- reserved: extensions, class, convention
- no prefix collision (foo vs foo-bar)
- fails at configuration time, not runtime
basics
~20 sAliases use letters, digits and the separators -, _, . which all map to dotted accessors. Names must start with a letter, can't be reserved words like extensions/class/convention, and the leading segment can't collide with another alias's prefix.
solid answer
~40 sCatalog alias names are constrained because Gradle generates **type-safe accessors** from them. Rules: - Allowed characters: ASCII letters, digits, and the separators **`-`**, **`_`**, **`.`** — and all three separators are treated identically, mapping to a nested accessor segment. So `commons-lang3`, `commons_lang3`, and `commons.lang3` all generate `libs.commons.lang3` (and would collide). - A name must start with a letter; sub-segments must be lowercase-friendly identifiers. - Certain names are **reserved** and rejected: `extensions`, `class`, `convention` (they'd clash with generated accessor internals). - **Prefix collisions are illegal**: you can't have both `foo` and `foo-bar`, because `foo` would need to be both a leaf accessor and a container for `foo.bar`. Violations fail catalog generation at configuration time with a clear message, so the build won't even reach task execution.
code
toml · 8 lines[libraries]
# both lines produce libs.commons.lang3 -> duplicate/collision
commons-lang3 = { module = "org.apache.commons:commons-lang3", version = "3.14.0" }
# commons.lang3 = { ... } # same accessor -> error
# prefix collision example (illegal together):
# foo = { module = "com.example:foo", version = "1.0" }
# foo-bar = { module = "com.example:foo-bar", version = "1.0" }go deeper
Know that dashes in aliases become dots in the accessor.
Know the separator equivalence and that invalid names fail the build.
Explain prefix collisions, reserved words, and configuration-time validation.
Define an org-wide alias naming convention to prevent collisions across a shared catalog.
## Why naming is constrained Gradle compiles each catalog into **generated accessor classes** (`libs.something.other`) so build scripts get IDE completion and compile-time safety. Because aliases become Java/Kotlin accessor paths, they must obey identifier-compatible rules. ## The separator equivalence The three separators `-`, `_`, and `.` are **interchangeable** and all become a dot in the accessor. This is the single most surprising rule: ```toml [libraries] commons-lang3 = { module = "org.apache.commons:commons-lang3", version = "3.14.0" } # accessor: libs.commons.lang3 ``` A direct consequence: `commons-lang3` and `commons.lang3` are the **same** alias and declaring both is a duplicate error. ## Reserved words and prefix collisions Because accessors are nested objects, an alias can't be both a value and a container: - **Prefix collision**: declaring `foo` and `foo-bar` together fails — `libs.foo` can't simultaneously be a dependency accessor and the `libs.foo.bar` namespace. - **Reserved names**: `extensions`, `class`, and `convention` are rejected because they clash with the generated API surface. ## Format rules - Start with a letter. - Segments contain only letters and digits after separator splitting. - The full set of allowed top-level prefixes is shared across `[libraries]`, `[bundles]`, and `[plugins]`, but the tables generate under different roots (`libs.x`, `libs.bundles.x`, `libs.plugins.x`), so a library and a plugin may share an alias without colliding. ## Failure mode Invalid names don't fail silently. Gradle validates the catalog while building the model, **before any task runs**, and reports a configuration-time error such as an invalid alias or a reserved-name violation. This is good: catalog typos can't slip into a build run. ## Example of an illegal catalog ```toml [libraries] foo = { module = "com.example:foo", version = "1.0" } foo-bar = { module = "com.example:foo-bar", version = "1.0" } # prefix collision with 'foo' -> error ``` ## Practical guidance Adopt a consistent separator (usually `-`) and a `group-artifact` or `domain-purpose` naming scheme. Keep aliases short but unambiguous, and avoid one alias being a strict prefix of another.
- Why can't you declare both `foo` and `foo-bar` in [libraries]?Because `libs.foo` would have to be both a dependency accessor and the namespace holding `libs.foo.bar`. An alias can't be a value and a container at once, so it's a prefix collision.
- When does Gradle report an invalid alias?At configuration time, while building the catalog model — before any task executes — so typos can't reach a build run.
saying these in an interview costs you the question
- Believing - and . are distinct in accessors — they collapse to the same path.
- Declaring an alias that's a strict prefix of another.
- Using reserved names like class or extensions as aliases.