Chapter 63. Maven Publishing (new)

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 'traditional' Maven publishing using the Upload task please see Chapter 49, 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 48, Dependency Management) and other tools that understand the Maven repository format.

63.1. The “maven-publish” Plugin

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.

Example 63.1. Applying the 'maven-publish' plugin

build.gradle

apply plugin: 'maven-publish'

Applying the “maven-publish” plugin does the following:

63.2. Publications

If you are not familiar with project artifacts and configurations, you should read the Chapter 49, 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, customising artifacts, and by modifying the generated POM file directly.

63.2.1. Publishing a Software Component

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 63.1. Software Components

Name Provided By Artifacts Dependencies
java Chapter 23, The Java Plugin Generated jar file Dependencies from 'runtime' configuration
web Chapter 26, 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 63.2. Adding a MavenPublication for a java component

build.gradle

publications {
        mavenJava(MavenPublication) {
            from components.java
        }
    }

63.2.2. Publishing custom artifacts

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 63.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 MavenPublication for more detailed documentation on how artifacts can be customised.

63.2.3. Identity values in the generated POM

The attributes of the generated POM file will contain identity values derived from the following project properties:

Certain repositories will not be able to handle all supported characters. For example, the ':' character cannot be used as an identifier when publishing to a filesystem-backed repository on Windows.

Note that you can set the value of these project properties in your build script, with the exception of name.

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.

63.2.4. Modifying the generated POM

At times, the POM file generated from the project information will need to be tweaked before publishing. The “maven-publish” plugin provides a hook to allow such modification.

Example 63.4. Modifying the POM file

build.gradle

publications {
        mavenCustom(MavenPublication) {
            pom.withXml {
                asNode().appendNode('description', 'A demonstration of maven pom customisation')
            }
        }
    }

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() for the relevant API reference documentation.

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.

63.3. Repositories

Publications are published to repositories. The repositories to publish to are defined by the PublishingExtension.getRepositories() container.

Example 63.5. Declaring repositories to publish to

build.gradle

repositories {
        maven {
            url "file://$buildDir/repo" // change to point to your repo, e.g. http://my.org/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.

63.4. Performing a publish

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 using the pattern "publish«NAME OF PUBLICATION»PublicationTo«NAME OF REPOSITORY»Repository".

Example 63.6. 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
        }
    }
    repositories {
        maven {
            url "file://$buildDir/repo" // change to point to your repo, e.g. http://my.org/repo
        }
    }
}

Output of gradle publish

> gradle publish
:generatePomFileForMavenJavaPublication
:compileJava
:processResources UP-TO-DATE
:classes
:jar
:publishMavenJavaPublicationToMavenRepository
:publish

BUILD SUCCESSFUL

Total time: 1 secs

So in this example a single PublishToMavenRepository task is be added, named 'publishMavenJavaPublicationToMavenRepository'. 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.

63.5. Publishing to Maven Local

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 using the pattern "publish«NAME OF PUBLICATION»PublicationToMavenLocal".

Example 63.7. 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

So in this example you can see that a single PublishToMavenLocal task is be added, 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.

63.6. Generating the POM file without publishing

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«NAME OF PUBLICATION»Publication". So in the below example where the publication is named "mavenCustom", the task will be named "generatePomFileForMavenCustomPublication".

Example 63.8. Generate a POM file without publishing

build.gradle

publishing {
    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 publishing block, as the above example demonstrates.

The same applies to any attempt to access publication-specific tasks like PublishToMavenRepository. These tasks should be referenced from within a publishing block.