Table of Contents
This chapter describes the new incubating Maven publishing support provided by the “maven-publish
”
plugin. Eventually this new publishing support will replace publishing via the Upload
task.
If you are looking for documentation on the original Maven publishing support using the Upload
task please see
Chapter 30, Publishing artifacts.
This chapter describes how to publish build artifacts to an Apache Maven Repository. A module published to a Maven repository can be consumed by Maven, Gradle (see Chapter 23, Dependency Management) and other tools that understand the Maven repository format.
The ability to publish in the Maven format is provided by the “maven-publish
” plugin.
The “publishing
” plugin creates an extension on the project named “publishing
” of type PublishingExtension
.
This extension provides a container of named publications and a container of named repositories. The “maven-publish
” plugin works with
MavenPublication
publications and MavenArtifactRepository
repositories.
Applying the “maven-publish
” plugin does the following:
publishing
” plugin
GenerateMavenPom
task for each MavenPublication
added (see Section 34.2, “Publications”).
PublishToMavenRepository
task
for the combination of each MavenPublication
added (see Section 34.2, “Publications”),
with each MavenArtifactRepository
added (see Section 34.3, “Repositories”).
PublishToMavenLocal
task
for each MavenPublication
added (seeSection 34.2, “Publications”).
If you are not familiar with project artifacts and configurations, you should read the Chapter 30, Publishing artifacts that introduces these concepts. This chapter also describes “publishing artifacts” using a different mechanism than what is described in this chapter. The publishing functionality described here will eventually supersede that functionality.
Publication objects describe the structure/configuration of a publication to be created. Publications are published to repositories via tasks, and the
configuration of the publication object determines exactly what is published. All of the publications of a project are defined in the
PublishingExtension.getPublications()
container. Each publication has a unique name within the project.
For the “maven-publish
” plugin to have any effect, a MavenPublication
must be added to the set of publications.
This publication determines which artifacts are actually published as well as the details included in the associated POM file.
A publication can be configured by adding components, customizing artifacts, and by modifying the generated POM file directly.
The simplest way to publish a Gradle project to a Maven repository is to specify a SoftwareComponent
to publish.
The components presently available for publication are:
Table 34.1. Software Components
Name | Provided By | Artifacts | Dependencies |
java |
Chapter 45, The Java Plugin | Generated jar file | Dependencies from 'runtime' configuration |
web |
Chapter 47, The War Plugin | Generated war file | No dependencies |
In the following example, artifacts and runtime dependencies are taken from the `java` component, which is added by the Java Plugin
.
Example 34.2. Adding a MavenPublication for a Java component
build.gradle
publishing { publications { mavenJava(MavenPublication) { from components.java } } }
It is also possible to explicitly configure artifacts to be included in the publication. Artifacts are commonly supplied as raw files, or as instances of
AbstractArchiveTask
(e.g. Jar, Zip).
For each custom artifact, it is possible to specify the extension
and classifier
values to use for publication. Note that
only one of the published artifacts can have an empty classifier, and all other artifacts must have a unique classifier/extension combination.
Configure custom artifacts as follows:
Example 34.3. Adding additional artifact to a MavenPublication
build.gradle
task sourceJar(type: Jar) {
from sourceSets.main.allJava
}
publishing {
publications {
mavenJava(MavenPublication) {
from components.java
artifact sourceJar {
classifier "sources"
}
}
}
}
See the MavenPublication
class in the API documentation for more information about how artifacts can be customized.
The attributes of the generated POM
file will contain identity values derived from the following project properties:
groupId
- Project.getGroup()
artifactId
- Project.getName()
version
- Project.getVersion()
Overriding the default identity values is easy: simply specify the groupId
, artifactId
or version
attributes when configuring the MavenPublication
.
Example 34.4. customizing the publication identity
build.gradle
publishing { publications { maven(MavenPublication) { groupId 'org.gradle.sample' artifactId 'project1-sample' version '1.1' from components.java } } }
Maven restricts 'groupId' and 'artifactId' to a limited character set ([A-Za-z0-9_\\-.]+
) and Gradle enforces this restriction.
For 'version' (as well as artifact 'extension' and 'classifier'), Gradle will handle any valid Unicode character.
The only Unicode values that are explicitly prohibited are '\
', '/
' and any ISO control character.
Supplied values are validated early in publication.
The generated POM file may need to be tweaked before publishing. The “maven-publish
”
plugin provides a hook to allow such modification.
Example 34.5. Modifying the POM file
build.gradle
publications { mavenCustom(MavenPublication) { pom.withXml { asNode().appendNode('description', 'A demonstration of maven POM customization') } } }
In this example we are adding a 'description' element for the generated POM. With this hook, you can modify any aspect of the POM. For example, you could replace the version range for a dependency with the actual version used to produce the build.
See MavenPom.withXml(org.gradle.api.Action)
in the API documentation for more information.
It is possible to modify virtually any aspect of the created POM should you need to. This means that it is also possible to modify the POM in such a way that it is no longer a valid Maven Pom, so care must be taken when using this feature.
The identifier (groupId, artifactId, version) of the published module is an exception; these values cannot be modified in the POM using the `withXML` hook.
Sometimes it's useful to publish multiple modules from your Gradle build, without creating a separate Gradle subproject. An example is publishing a separate API and implementation jar for your library. With Gradle this is simple:
Example 34.6. Publishing multiple modules from a single project
build.gradle
task apiJar(type: Jar) { baseName "publishing-api" from sourceSets.main.output exclude '**/impl/**' } publishing { publications { impl(MavenPublication) { groupId 'org.gradle.sample.impl' artifactId 'project2-impl' version '2.3' from components.java } api(MavenPublication) { groupId 'org.gradle.sample' artifactId 'project2-api' version '2' artifact apiJar } } }
If a project defines multiple publications then Gradle will publish each of these to the defined repositories. Each publication must be given a unique identity as described above.
Publications are published to repositories. The repositories to publish to are defined by the PublishingExtension.getRepositories()
container.
Example 34.7. Declaring repositories to publish to
build.gradle
publishing { repositories { maven { // change to point to your repo, e.g. http://my.org/repo url "$buildDir/repo" } } }
The DSL used to declare repositories for publication is the same DSL that is used to declare repositories to consume dependencies from,
RepositoryHandler
. However, in the context of Maven publication only
MavenArtifactRepository
repositories can be used for publication.
The “maven-publish
” plugin automatically creates a PublishToMavenRepository
task for each MavenPublication
and MavenArtifactRepository
combination in the publishing.publications
and publishing.repositories
containers respectively.
The created task is named “publish«PUBNAME»PublicationTo«REPONAME»Repository
”.
Example 34.8. Publishing a project to a Maven repository
build.gradle
apply plugin: 'java' apply plugin: 'maven-publish' group = 'org.gradle.sample' version = '1.0' publishing { publications { mavenJava(MavenPublication) { from components.java } } } publishing { repositories { maven { // change to point to your repo, e.g. http://my.org/repo url "$buildDir/repo" } } }
Output of gradle publish
> gradle publish :generatePomFileForMavenJavaPublication :compileJava :processResources UP-TO-DATE :classes :jar :publishMavenJavaPublicationToMavenRepository :publish BUILD SUCCESSFUL Total time: 1 secs
In this example, a task named “publishMavenJavaPublicationToMavenRepository
” is created, which is of type
PublishToMavenRepository
.
This task is wired into the publish
lifecycle task.
Executing “gradle publish
” builds the POM file and all of the artifacts to be published, and transfers them to the repository.
For integration with a local Maven installation, it is sometimes useful to publish the module into the local .m2 repository. In Maven parlance, this is
referred to as 'installing' the module. The “maven-publish
” plugin makes this easy to do by automatically creating a
PublishToMavenLocal
task for each MavenPublication
in the publishing.publications
container. Each of these tasks is wired into the publishToMavenLocal
lifecycle task.
You do not need to have `mavenLocal` in your `publishing.repositories` section.
The created task is named “publish«PUBNAME»PublicationToMavenLocal
”.
Example 34.9. Publish a project to the Maven local repository
Output of gradle publishToMavenLocal
> gradle publishToMavenLocal :generatePomFileForMavenJavaPublication :compileJava :processResources UP-TO-DATE :classes :jar :publishMavenJavaPublicationToMavenLocal :publishToMavenLocal BUILD SUCCESSFUL Total time: 1 secs
The resulting task in this example is named “publishMavenJavaPublicationToMavenLocal
”. This task is wired into the publishToMavenLocal
lifecycle task.
Executing “gradle publishToMavenLocal
” builds the POM file and all of the artifacts to be published, and “installs” them into the local Maven repository.
At times it is useful to generate a Maven POM file for a module without actually publishing. Since POM generation is performed by a separate task, it is very easy to do so.
The task for generating the POM file is of type GenerateMavenPom
, and it is given a name based on the name
of the publication: “generatePomFileFor«PUBNAME»Publication
”. So in the example below,
where the publication is named “mavenCustom
”,
the task will be named “generatePomFileForMavenCustomPublication
”.
Example 34.10. Generate a POM file without publishing
build.gradle
model {
tasks.generatePomFileForMavenCustomPublication {
destination = file("$buildDir/generated-pom.xml")
}
}
Output of gradle generatePomFileForMavenCustomPublication
> gradle generatePomFileForMavenCustomPublication :generatePomFileForMavenCustomPublication BUILD SUCCESSFUL Total time: 1 secs
All details of the publishing model are still considered in POM generation, including components
`, custom artifacts
,
and any modifications made via pom.withXml
.
The “maven-publish
” plugin leverages some experimental support for late plugin configuration,
and any GenerateMavenPom
tasks will not be constructed until the publishing extension is configured.
The simplest way to ensure that the publishing plugin is configured when you attempt to access the GenerateMavenPom
task
is to place the access inside a model
block, as the example above demonstrates.
The same applies to any attempt to access publication-specific tasks like PublishToMavenRepository
.
These tasks should be referenced from within a model
block.