Upload your library

Stay organized with collections Save and categorize content based on your preferences.

To grant access to your library, you need to choose how you want to distribute it. This page guides you through the considerations related to choosing a distribution mechanism and shows how to create a publication using the Maven Publish Plugin.

Before uploading your library, make sure you have prepared your library for release and configured any publication variants or test fixtures needed.

Choose a distribution mechanism

Libraries are published as AAR files. These files contain code (bytecode and native libraries), an Android manifest, and resources. The package itself does not declare any identity, version, or dependencies on other libraries.

Repositories versus direct distribution

There are two possible ways to make your library available to others:

  • Use a repository.
  • Provide the AAR directly to your customers (through email, or online storage like Google Drive for instance).

Distributing the AAR directly does not provide your user with any information regarding the identity, version, or dependencies of your library. When publishing to a repository, this is handled by a separate file that is part of the repository mechanism. For Maven repositories, this is the POM file. Therefore, it is strongly recommended to publish libraries using repositories rather than manually distributing AAR files.

There are multiple benefits to using a repository to publish your library:

  • Gradle can automatically add your library’s dependencies to the dependency graph.
  • Gradle can ensure that a single version of your library is in the dependency graph, resolving conflicts if your library is transitively included more than once with different versions.
  • AGP can do more efficient desugaring (if your library is using Java 8 or higher language features), reducing build times for your users.
  • Your library can use variant publishing and include features like test fixtures.

Providing AARs through a repository is generally the best practice. It helps users have a better understanding of where the library is coming from (rather than having to deal with a name.aar file without important details, like version). When upgrading to a newer version of the library, using a repository helps ensure that only the required dependencies of the newer version are added, so that users won’t have to manually update dependencies.

Types of repositories

There are three types of repositories:

  • Free online repositories, like MavenCentral, allow anyone to upload and download libraries.
  • Private repositories, with access via login, allow controlled distribution of private libraries.
  • Local, folder-based repositories allow distribution of libraries through manual download.

Using local, folder-based repositories is very similar to providing your users with a manual download link to the AAR, or sending the AAR by email. The main difference is that you are not sending just the AAR but also the additional information about identity, version, and dependencies. What you actually distribute is a zip file of the folder-based repository containing your AAR, plus the metadata. Your users can then unzip the zip file, add the unzipped content to their project, and point Gradle to it. From then on, they can declare a dependency on the library using Maven coordinates, as if the library were in an online repository, and benefit from all the advantages mentioned earlier.

Create the publication

Publishing is done using the Gradle Maven Publish Plugin. The Maven Publish Plugin allows you to declare publications and repositories, and creates tasks to publish these publications to the repositories. These publications consume a SoftwareComponent instance which is created by the plugin that drives the build, which could be AGP or the java-library plugin.

Note that when running the Maven Publish Plugin with AGP, the software components are not created right when the plugin is applied. They are instead created during the afterEvaluate() callback step. Therefore the publication that selects the software component must also be configured during the afterEvaluate() step.

The following code snippet of the module-level build.gradle file creates a publication for a given variant created with singleVariant() or multipleVariants().

Groovy

publishing {
  publications {
    release(MavenPublication) {
      groupId = 'com.my-company'
      artifactId = 'my-library'
      version = '1.0'

      afterEvaluate {
        from components.release
      }
    }
  }
}

Kotlin

publishing {
  publications {
    register<MavenPublication>("release") {
      groupId = "com.my-company"
      artifactId = "my-library"
      version = "1.0"

      afterEvaluate {
        from(components["release"])
      }
    }
  }
}

In the example above, the name of the component (components.release) is based on the name that was given to either singleVariant(), or multipleVariants().

Once you declare a publication, you must create a target repository. See the Gradle documentation on the Maven Publish Plugin for more information.

Publish to a local repository

Publishing to a local repository is very similar to publishing to a remote repository, except for the repository declaration. First, refer to the previous section on how to publish to a remote repository to create a publication that publishes the desired variant or variants.

Then create a local repository:

Groovy

publishing {
  publications {
    release(MavenPublication) {
      ...
    }
  }
  repositories {
    maven {
      name = 'myrepo'
      url = "${project.buildDir}/repo"
    }
  }
}

Kotlin

publishing {
  publications {
    register<MavenPublication>("release") {
      ...
    }
  }
  repositories {
    maven {
      name = "myrepo"
      url = uri("${project.buildDir}/repo")
    }
  }
}

This creates a task called publishReleaseToMyrepoRepository, that is made up of the name of the publication and the name of the repository. Running this task generates the repository to the location provided, here inside the build folder of the project, under a repository directory.

If you wish to automatically generate a zip file of the repository, you can do so using the following code:

Groovy

tasks.register('generateRepo', Zip) {
  def publishTask = tasks.named('publishReleasePublicationToMyrepoRepository')
  from publishTask.map { it.getRepository().getUrl() }
  into 'mylibrary'
  archiveFileName.set('mylibrary.zip')
}

Kotlin

tasks.register<Zip>("generateRepo") {
  val publishTask = tasks.named(
    "publishReleasePublicationToMyrepoRepository",
    PublishToMavenRepository::class.java)
  from(publishTask.map { it.repository.url })
  into("mylibrary")
  archiveFileName.set("mylibrary.zip")
}

This code creates a Zip task called generateRepo that consumes the content of the publishing task and zips it while ensuring that the zip entries are in a top-level folder called mylibrary. The output is located under build/distributions.