skip to content

What is a <classifier> in Maven and when would you use one?

level: seniorimportance: should knowfreq 45%

answer

  1. extra suffix on filename
  2. -sources / -javadoc / -tests
  3. same GAV, different file
  4. platform/variant builds
  5. not a replacement for artifactId

basics

~20 s

A classifier is an optional extra coordinate appended to the artifact filename, letting one GAV publish several distinct artifacts — for example -sources, -javadoc, or platform-specific builds — that share the same groupId, artifactId, and version.

solid answer

~40 s

A classifier distinguishes multiple artifacts that all share the same groupId/artifactId/version. The filename becomes <artifactId>-<version>-<classifier>.<ext>. The canonical uses are secondary artifacts produced alongside the main jar: -sources (source jar) and -javadoc, both attached automatically by their plugins. It's also used for variant builds — e.g. a -jdk8 vs -jdk11 build, or platform natives like -linux-x86_64. To depend on a classified artifact you add <classifier> to the dependency. A subtle point: classifier is NOT a substitute for a separate artifactId; transitive dependency mediation and many tools treat the GAV as the identity, so overusing classifiers for fundamentally different modules causes confusion. Use them for true variants/companions of one logical artifact.

code

xml · 8 lines
xml
<dependency>
  <groupId>com.example</groupId>
  <artifactId>core</artifactId>
  <version>1.0.0</version>
  <type>test-jar</type>
  <classifier>tests</classifier>
  <scope>test</scope>
</dependency>

go deeper

for a junior

Recognize -sources and -javadoc as classifier artifacts.

for a middle

Know the filename pattern and how to depend on a classified artifact including test-jars.

for a senior

Judge when classifiers are appropriate (variants/companions) vs when a separate artifactId is better.

for a principal

Set conventions for native/variant publishing and test-jar reuse, and understand classifier impact on graph tooling and mediation.

## The problem classifiers solve Normally one set of coordinates (GAV) maps to one file. But sometimes a single project legitimately needs to publish **several files** that share the same identity — the compiled jar, plus its sources, plus its javadoc, plus maybe a native build for each OS. The **classifier** is the extra coordinate that disambiguates them. ## How it appears in the filename The artifact filename is: ``` <artifactId>-<version>[-<classifier>].<extension> ``` So for `commons-lang3` version `3.14.0`: - `commons-lang3-3.14.0.jar` — main artifact (no classifier) - `commons-lang3-3.14.0-sources.jar` — classifier `sources` - `commons-lang3-3.14.0-javadoc.jar` — classifier `javadoc` ## Common classifiers - **sources** — attached by `maven-source-plugin` (`source:jar`). - **javadoc** — attached by `maven-javadoc-plugin`. - **tests** — a test-jar of your test classes, attached by `maven-jar-plugin:test-jar`, so other modules can reuse test utilities. - **Platform/variant** — e.g. `linux-x86_64`, `windows`, `jdk8`. Common for native libraries (JavaCPP, LWJGL, etc.). ## Depending on a classified artifact ```xml <dependency> <groupId>com.example</groupId> <artifactId>native-lib</artifactId> <version>2.0.0</version> <classifier>linux-x86_64</classifier> </dependency> ``` To reuse another module's test classes: ```xml <dependency> <groupId>com.example</groupId> <artifactId>core</artifactId> <version>1.0.0</version> <type>test-jar</type> <classifier>tests</classifier> <scope>test</scope> </dependency> ``` ## When NOT to use a classifier A classifier is for **companion or variant** artifacts of one logical thing. It is not a replacement for giving genuinely different modules their own `artifactId`. Dependency mediation and reporting tools key on GAV, so abusing classifiers to ship unrelated jars under one GAV creates confusing graphs.

  • Which plugins attach the sources and javadoc classifiers?
    maven-source-plugin attaches -sources, and maven-javadoc-plugin attaches -javadoc, typically bound to the package phase or a release profile.
  • How do you consume another module's test classes?
    Depend on it with <type>test-jar</type> and <classifier>tests</classifier>; the producing module must run maven-jar-plugin's test-jar goal.

saying these in an interview costs you the question

  • Confusing classifier with packaging/type
  • Using a classifier instead of a distinct artifactId for an unrelated module
  • Assuming classified artifacts are resolved transitively the same as the main artifact (they are not auto-pulled)

context