Explain the extended string notation with a classifier and extension, e.g. `group:name:version:classifier@ext`. When is it needed?
answer
- 4th segment = classifier
- @ext = non-default packaging
- combine: g:n:v:classifier@ext
- @ext is artifact-only (no transitives)
- equivalent to map classifier/ext keys
basics
~10 sAppend :classifier to add a classifier and @ext to set a non-default extension: "io.netty:netty...:4.1.107.Final:linux-x86_64" or "group:name:1.0@zip". Needed for native/platform artifacts, sources/javadoc, or non-jar packaging.
solid answer
~40 sGradle's string notation has an extended form that carries a **classifier** and/or an **extension** beyond plain GAV. The classifier is a fourth colon segment — `"group:name:version:classifier"` — used for platform-specific or qualified artifacts like native builds (`linux-x86_64`) or `sources`/`javadoc`. The extension uses an `@` suffix — `"group:name:version@ext"` — to request a non-default packaging such as `zip`, `aar`, or `pom` instead of the default `jar`. They combine: `"group:name:version:classifier@ext"`. One nuance: the `@ext` form is an **artifact-only** notation — by default it suppresses transitive resolution for that artifact (you fetch just that file). It's functionally equivalent to using map notation with `classifier`/`ext` keys; choose whichever reads better. In practice teams reach for it occasionally for native libraries or to pull a specific non-jar artifact, and otherwise stick to plain `g:n:v`.
code
kotlin · 6 linesdependencies {
// classifier only — resolves transitively as normal
runtimeOnly("io.netty:netty-transport-native-epoll:4.1.107.Final:linux-x86_64")
// @ext — artifact-only, transitives suppressed by default
implementation("com.example:assets:1.0@zip")
}go deeper
Recognize that you can tack a classifier or @ext onto the string; deep nuance not expected.
Show the g:n:v:classifier@ext shape, give a native-library example, and note the @ext artifact-only/no-transitives behavior.
Explain equivalence to map notation, when the transitive-suppression of @ext bites, and when to prefer each form.
Discuss portability concerns of classifier-pinned native artifacts across platforms and how to manage them cleanly in a shared build.
## Beyond plain GAV in a string The compact `"group:name:version"` can't express a classifier or a non-jar extension. The **extended string notation** adds both, so you don't always need map notation: - **Classifier** — a fourth colon segment: `"group:name:version:classifier"`. - **Extension** — an `@`-suffixed type: `"group:name:version@ext"`. - **Both** — `"group:name:version:classifier@ext"`. ```kotlin dependencies { // native, platform-specific classifier runtimeOnly("io.netty:netty-transport-native-epoll:4.1.107.Final:linux-x86_64") // non-default packaging via @ext (artifact-only) implementation("com.example:bundle:1.0@zip") } ``` ## What classifier and ext mean - **classifier** — a qualifier baked into the artifact file name: `guava-33.0.0-jre-sources.jar` has classifier `sources`; native libs ship classifiers like `linux-x86_64`, `osx-aarch_64`. - **ext** — the file extension / packaging type. Defaults to `jar`; set it for `zip`, `aar`, `pom`, etc. ## The `@ext` transitive nuance The `@ext` form is treated as an **artifact-only** dependency: Gradle fetches *that specific artifact* and, by default, does **not** pull transitive dependencies for it. That's usually fine for a self-contained `zip`/native file, but it's a gotcha if you expected transitives — in that case use map notation (or add a configuring block) instead. The fourth-segment classifier *without* `@ext` still resolves normally. ## Equivalence to map notation ```kotlin // these declare the same thing runtimeOnly("io.netty:netty-transport-native-epoll:4.1.107.Final:linux-x86_64") runtimeOnly(group = "io.netty", name = "netty-transport-native-epoll", version = "4.1.107.Final", classifier = "linux-x86_64") ``` Use the string form for brevity; use map notation when a segment is computed or readability suffers. ## When you actually need it - Native/platform-specific libraries selected by classifier. - Pulling `sources`/`javadoc` artifacts deliberately. - Non-jar packaging (`zip`, `aar`, `pom`) via `@ext`. Otherwise plain `g:n:v` is the right default.
- Does `"group:name:1.0@zip"` pull transitive dependencies?No — the `@ext` form is artifact-only and suppresses transitive resolution by default; you get just that artifact. Use map notation or a configuring block if you need transitives.
- Is the extended string form more powerful than map notation?No, they're equivalent for classifier/ext; map notation just reads better for computed segments and is clearer about intent.
saying these in an interview costs you the question
- Assuming `@ext` declarations still bring transitive dependencies (they're artifact-only by default).
- Confusing the fourth segment (classifier) with the `@`-suffix (extension).
- Thinking the extended string form does something map notation cannot.