Classifier
About
The <classifier> element in Maven is an optional part of artifact coordinates. It is used to distinguish artifacts that are built from the same project but serve different purposes.
The classifier adds an extra label to the artifact name and allows us to attach and retrieve alternate artifacts, such as source code, documentation, or test versions, without changing the main artifact details.
Maven projects may need to generate or consume more than one artifact from the same codebase. Using a classifier helps:
Identify different types of outputs (e.g., main JAR, test JAR, source JAR)
Separate OS-specific or environment-specific builds
Attach custom builds in CI/CD pipelines
Coordinate Format
An artifact with a classifier has this format:
<groupId>:<artifactId>:<version>:<classifier>Example:
com.example:utility-lib:1.0.0:sourcesThis refers to the sources JAR of version 1.0.0 of utility-lib.
1. classifier - sources
What It Means
The sources classifier is used to publish or consume a JAR file that contains the source code of a Maven project. This is typically used to:
Make the source code available to developers using the library.
Enable IDE features like "Go to definition", "View source", and debugging inside dependencies.
Improve traceability and code visibility during integration or support.
When to Use
We use the sources classifier when:
We are publishing a library and want to include the readable
.javasource files for other developers.We are consuming a dependency and want to download and attach its source code (commonly done by IDEs).
We want to debug into external library code.
How It Works
-> Without Classifier
Maven typically builds and installs:
my-lib-1.0.0.jar → Compiled .class files-> With sources Classifier
An additional artifact is created:
my-lib-1.0.0-sources.jar → Contains .java source filesBoth are deployed to the Maven repository, and the sources JAR can be retrieved using the classifier.
Publishing Sources with Maven
Step 1: Use maven-source-plugin
maven-source-pluginThis plugin creates a separate JAR that contains all .java source files.
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>3.2.1</version>
<executions>
<execution>
<id>attach-sources</id>
<phase>verify</phase>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>This will generate a my-lib-1.0.0-sources.jar in the target/ directory and attach it to the build.
Step 2: Install or Deploy
To install to local repository:
mvn clean installTo deploy to remote repository:
mvn clean deployBoth the main JAR and the sources JAR will be uploaded.
Consuming Source JAR in Another Project
To explicitly add the source JAR via classifier:
<dependency>
<groupId>com.example</groupId>
<artifactId>my-lib</artifactId>
<version>1.0.0</version>
<classifier>sources</classifier>
</dependency>This will only bring in the my-lib-1.0.0-sources.jar and not the compiled classes.
Note: In real-world use, developers rarely add the
sourcesJAR manually. IDEs like IntelliJ and Eclipse auto-fetch them if available.
2. classifier - classes
What It Means
The classes classifier is used to generate and attach a JAR containing only the compiled .class files, excluding other resources, metadata, or bundled dependencies. It differs from the default JAR in that it:
Does not include
META-INF/,resources/, or other files fromsrc/main/resourcesIs typically used when we need a pure bytecode-only output
When to Use
We might use classifier=classes when:
We need just the compiled classes to embed or bundle elsewhere.
We are creating multiple variants of our artifact for a framework or platform.
We are building a custom artifact (e.g., a stripped-down version without resources or META-INF).
We are developing a multi-module project where some modules only need raw
.classfiles from others (e.g., code generators, transformation tools).
How It Works
Standard Build Output
By default, Maven creates:
my-lib-1.0.0.jar → Includes compiled .class files + resources + META-INFWith classifier=classes
It creates:
my-lib-1.0.0-classes.jar → Only compiled .class files from /target/classesHow to Generate a classes JAR
classes JARStep 1: Use maven-jar-plugin to attach a classes JAR
maven-jar-plugin to attach a classes JAR<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.3.0</version>
<executions>
<execution>
<id>attach-classes-jar</id>
<phase>package</phase>
<goals>
<goal>jar</goal>
</goals>
<configuration>
<classifier>classes</classifier>
<includes>
<include>**/*.class</include>
</includes>
<excludes>
<exclude>META-INF/**</exclude>
</excludes>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>Step 2: Run the build
mvn clean packageThe target/ directory will contain:
my-lib-1.0.0.jar(default)my-lib-1.0.0-classes.jar(only.classfiles)
Consuming the classes JAR
classes JARIf another module or project wants to depend only on the .class content, it can declare:
<dependency>
<groupId>com.example</groupId>
<artifactId>my-lib</artifactId>
<version>1.0.0</version>
<classifier>classes</classifier>
</dependency>This brings in only the stripped-down compiled code.
3. classifier - api
What It Means
The api classifier is used to attach a JAR containing API specification files—most commonly OpenAPI (Swagger) YAML or JSON files. It allows developers to:
Distribute machine-readable API contracts independently of the main code.
Enable clients or consumers to generate client SDKs.
Share API definition artifacts in CI/CD pipelines.
Version API contracts separately from the implementation logic.
When to Use
Use classifier=api when:
We want to publish an OpenAPI spec (
openapi.yaml,openapi.json) as a standalone artifact.We are working in a contract-first or API-first architecture.
We have multiple teams where one team owns the API and another consumes it.
We want to let consumers generate clients using tools like Swagger Codegen or OpenAPI Generator.
How It Works
Standard Build Output
By default, Maven creates:
my-service-1.0.0.jar → Application classes and resourcesWith classifier=api
We generate an additional artifact:
my-service-1.0.0-api.jar → Contains only OpenAPI spec files (e.g., openapi.yaml)This allows publishing and versioning the API specification alongside the service, but independently usable.
How to Generate an api JAR
api JARWe manually or automatically place OpenAPI spec files (like openapi.yaml) under a known directory, and attach them using the maven-jar-plugin.
Step 1: Place API Spec in a Directory
Place our OpenAPI file at:
src/main/api/openapi.yamlStep 2: Configure maven-jar-plugin to attach it
maven-jar-plugin to attach it<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.3.0</version>
<executions>
<execution>
<id>attach-api-jar</id>
<phase>package</phase>
<goals>
<goal>jar</goal>
</goals>
<configuration>
<classifier>api</classifier>
<includes>
<include>**/*.yaml</include>
<include>**/*.yml</include>
<include>**/*.json</include>
</includes>
<basedir>${project.basedir}/src/main/api</basedir>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>This tells Maven to package the API files from src/main/api into a JAR with the api classifier.
Step 3: Run the Build
mvn clean packageOutput:
target/my-service-1.0.0.jar→ default application JARtarget/my-service-1.0.0-api.jar→ contains onlyopenapi.yamlor similar
Consuming the API Spec in Another Project
Other teams or modules can now depend on the published API artifact:
<dependency>
<groupId>com.mycompany.services</groupId>
<artifactId>my-service</artifactId>
<version>1.0.0</version>
<classifier>api</classifier>
</dependency>This can be used by:
Code generation tools to build client stubs
API documentation sites
Linter/contract validator plugins in CI
4. classifier - javadoc
What It Means
The javadoc classifier is used to attach a separate JAR that contains Javadoc-generated HTML documentation for a project’s public API. This classifier allows developers to:
Publish human-readable API documentation as a separate artifact.
Let consuming developers explore classes and methods directly in IDEs.
Maintain documentation versioned alongside the codebase.
When to Use
Use the javadoc classifier when:
We want to distribute HTML documentation for a library.
We are building a reusable SDK or module used by other teams.
We want documentation to be browsable inside IDEs or on artifact repository websites.
We want to expose a stable API to external clients while hiding implementation details.
How It Works
Without Classifier
Standard Maven build produces:
my-lib-1.0.0.jar → compiled code + resourcesWith classifier=javadoc
We generate an additional artifact:
my-lib-1.0.0-javadoc.jar → contains `index.html` and related Javadoc filesThis artifact can be attached and deployed along with the main JAR.
How to Generate a Javadoc JAR
Step 1: Use the maven-javadoc-plugin
maven-javadoc-pluginAdd the following plugin to our pom.xml:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>3.6.3</version>
<executions>
<execution>
<id>attach-javadoc</id>
<goals>
<goal>jar</goal>
</goals>
<phase>verify</phase>
</execution>
</executions>
</plugin>
</plugins>
</build>This tells Maven to generate Javadoc and attach it as a JAR with classifier javadoc.
Step 2: Run the Build
mvn clean verifyOutput in the target/ directory:
my-lib-1.0.0.jar→ compiled application/librarymy-lib-1.0.0-javadoc.jar→ generated API docs
Consuming the Javadoc JAR
To explicitly include the Javadoc artifact:
<dependency>
<groupId>com.example</groupId>
<artifactId>my-lib</artifactId>
<version>1.0.0</version>
<classifier>javadoc</classifier>
</dependency>Note: In practice, developers rarely add this manually. Tools like IntelliJ IDEA and Eclipse auto-download the Javadoc if available in the repository.
5. classifier - tests
What It Means
The tests classifier is used to package and attach a JAR that contains the compiled test classes (usually from src/test/java). This allows us to:
Share common test utilities and base classes between modules.
Create dedicated test libraries reused across projects.
Enable integration tests or functional tests to depend on unit test components of another module.
This JAR is not built by default in Maven and requires manual configuration.
When to Use
Use classifier=tests when:
We have reusable test utilities, base test classes, or mocks needed in other modules.
We are creating a shared testing framework for an internal team.
We want to isolate test logic from production logic but still distribute it.
We are testing libraries that require simulation or shared mock data.
How It Works
Normal Maven Build
Produces:
my-lib-1.0.0.jar → compiled main classes onlyWith classifier=tests
We generate:
my-lib-1.0.0-tests.jar → compiled test classes from `src/test/java`This allows other projects to include test code separately from production code.
How to Generate a Test JAR
Step 1: Use maven-jar-plugin
maven-jar-pluginAdd the following plugin configuration to pom.xml:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.3.0</version>
<executions>
<execution>
<id>attach-tests</id>
<goals>
<goal>test-jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>This will create a JAR from the src/test/java directory and attach it with the tests classifier.
Step 2: Run the Build
mvn clean packageWe’ll now see in the target/ directory:
my-lib-1.0.0.jar→ main compiled codemy-lib-1.0.0-tests.jar→ compiled test classes only
Consuming the Test JAR in Another Module
Another module that wants to reuse the test classes can add a dependency like:
<dependency>
<groupId>com.example</groupId>
<artifactId>my-lib</artifactId>
<version>1.0.0</version>
<classifier>tests</classifier>
<scope>test</scope>
</dependency>The
scopeshould be set totestto avoid this code leaking into production classpath.Maven will resolve and include the test-only JAR during test compilation of the consuming module.
6. classifier - platform-specific
What It Means
The platform-specific classifier is used to publish artifacts targeted for a specific operating system or hardware architecture. It allows us to:
Deliver native binaries (
.so,.dll,.dylib) tailored to a platform.Provide different configurations or compiled results per platform.
Maintain consistent artifact coordinates across platforms while delivering different contents.
This classifier is often used in:
JNI (Java Native Interface) bindings
Cross-platform CLI tools
Embedded systems
Libraries that integrate with native SDKs or drivers
When to Use
Use platform-specific classifiers when:
We build and package different binaries per platform (e.g., Linux vs. Windows vs. macOS).
We Java code wraps native libraries using JNI or JNA.
Our app requires platform-specific launchers or shell scripts.
We distribute executable wrappers like
.exe,.sh,.bat.
How It Works
Let’s say our project image-processor builds a shared native library using C/C++ and JNI. We compile this native library separately for:
Linux (x86_64)
macOS (ARM64)
Windows (x64)
We package each output as a separate artifact with a unique classifier:
image-processor-1.0.0-linux-x86_64.jar
image-processor-1.0.0-mac-arm64.jar
image-processor-1.0.0-windows-x64.jarAll these have the same groupId, artifactId, and version, but differ in classifier.
How to Build and Attach Platform-Specific Artifacts
Step 1: Build native libraries for each platform
We typically do this using external build tools like:
CMake
Gradle with JNI support
Docker (for cross-compilation)
Let’s assume each native binary is named:
libimageproc.sofor Linuxlibimageproc.dylibfor macOSimageproc.dllfor Windows
Step 2: Place the binary in a custom directory, like:
src/main/native/linux-x86_64/
src/main/native/mac-arm64/
src/main/native/windows-x64/Step 3: Configure maven-jar-plugin for each classifier
maven-jar-plugin for each classifierWe can use Maven profiles to create different platform-specific JARs:
<profiles>
<profile>
<id>linux-x86_64</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.3.0</version>
<executions>
<execution>
<id>attach-linux</id>
<phase>package</phase>
<goals>
<goal>jar</goal>
</goals>
<configuration>
<classifier>linux-x86_64</classifier>
<basedir>${project.basedir}/src/main/native/linux-x86_64</basedir>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>Repeat for other platforms (mac-arm64, windows-x64) using separate profiles.
Step 4: Build each classifier version
mvn clean package -Plinux-x86_64
mvn clean package -Pmac-arm64
mvn clean package -Pwindows-x64Each command generates a different artifact with a platform-specific classifier.
Consuming Platform-Specific Artifact
In another project, depending on the runtime platform, use the appropriate dependency:
<dependency>
<groupId>com.example</groupId>
<artifactId>image-processor</artifactId>
<version>1.0.0</version>
<classifier>linux-x86_64</classifier>
</dependency>To make this dynamic, we can write platform-detection logic or let our CI/CD or packaging tool resolve the correct artifact based on OS.
Last updated