How to build sources JAR with Gradle?
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
A sources JAR packages the source files that belong to a published library so IDEs and developers can inspect the implementation behind the compiled classes. In modern Gradle builds, the simplest way to produce it is usually withSourcesJar(), which is cleaner than older hand-written Jar tasks.
The Modern Gradle Way
If your project uses the Java plugin, the recommended setup is short.
After that, run:
Gradle creates a sourcesJar task and writes the artifact into build/libs with a -sources.jar classifier.
This is usually the right answer for standard Java libraries because it follows Gradle's built-in conventions and works naturally with publishing plugins.
Manual Task for Older or Customized Builds
You can still define the sources JAR task manually when you need special behavior or are maintaining an older build style.
This gives more control. For example, you can add generated sources or exclude certain files. But for ordinary projects, the built-in API is simpler and less error-prone.
Publish It with maven-publish
Generating the file is one step. Publishing it is another.
If you use maven-publish together with withSourcesJar(), the sources artifact is attached automatically when you publish the Java component.
That means the published module includes the main artifact and the sources JAR together, which is what repository consumers usually expect.
Include the Right Source Set
A sources JAR should normally contain the main published source set, not tests and not arbitrary project files.
For example, with a manual task:
If your project generates sources, decide deliberately whether those generated files belong in the published sources artifact. Sometimes they help consumers, but sometimes they only add noise.
Verify the Artifact
Before publishing, inspect the JAR contents to make sure the expected files are present.
This catches configuration mistakes early, such as the wrong source set or a missing classifier.
Kotlin and Mixed Builds
If the project uses Kotlin or a mixed Java-Kotlin setup, the idea stays the same but the exact plugin wiring may differ. The important point is that the sources artifact should be attached through the component model used by the project rather than bolted on awkwardly afterward.
So the guiding principle is to stay inside Gradle's publishing conventions unless the build genuinely needs custom packaging behavior.
Common Pitfalls
Writing a custom task when withSourcesJar() already solves the problem is the most common unnecessary complication.
Another frequent mistake is generating the sources JAR but not attaching it to the publication, which means the artifact exists locally but never reaches the repository.
Using the wrong source set also causes confusion. A sources JAR for a library should normally package the main sources, not tests.
Finally, copying outdated Gradle examples can lead to builds that work but ignore the current plugin model and publishing conventions.
Summary
- for modern Java builds,
java { withSourcesJar() }is the preferred Gradle solution - a manual
Jartask still works when you need custom behavior - generating the sources JAR is separate from publishing it
- verify the artifact contents before publishing
- prefer built-in Gradle conventions unless the project has a real reason to override them

