Publishing Android Library to Bintray

Raka Westu Mogandhi
prismapp
Published in
5 min readApr 21, 2017

In my previous post about Android library project initialization I wrote how to write our own library or module to support our main application. Look at library dependencies at your gradle script.

compile 'com.android.support:appcompat-v7:25.2.0'

Above code was an example of a Maven library that we includes in our application.

In this post I will talk more about how I publish library to public maven repository such as bintray, maven central, etc so people can start using your library easier with same code format as above code example.

Basically if we want to publish a library in maven repository we need to have several things:

  • The artifacts → binary that we want to publish. For example: jar (Java library) file, aar (Android library) file, pods (iOS library) file.
  • Group identifier → publisher identifier. Mostly domain name for easier publisher identification. For example: com.domain.sdk.
  • Artifact identifier → library or artifact identifier. Mostly library name for easier library identifier in specific group. For example: payment-module.
  • Version name → to identify revision of library. For example: 1.2.1.

Above items was minimum things needed to publish and use the library. In Maven it was included on pom.xml file. The pom.xml file is the core of a project’s configuration in Maven. It includes many information to build and use the library project.

For library user they will just have define the library like this in their gradle script.

compile 'com.domain.sdk:payment-module:1.2.1'

Easy, isn’t it? Of course this maven repository was made to realize above dependencies concept in modern Android or Java development.

There are several optional things to considerate when publishing library.

  • External dependencies → if your library needs another library you can includes it by knowing the group identifier, artifact identifier and also the latest version name.
  • More project details → project name, description, url, licenses, etc. you can define to explain more about your library project.

So the bare minimum generated pom.xml file should be like this.

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<groupId>com.domain.sdk</groupId>
<artifactId>payment-module</artifactId>
<version>1.2.1</version>
<packaging>aar</packaging>
<dependencies>
<dependency>
<groupId>com.android.support</groupId>
<artifactId>appcompat-v7</artifactId>
<version>25.2.0</version>
</dependency>
</dependencies>
</project>

Note:
Above example was basic usage for Android library Maven publication. For more information about Maven concept you can take a look at this reference.

So, now we have grasped the concept behind Android library publication by using Maven. The next step is to know how we can use its concept in our library so we can publish it and people can start using it. If your Android project was already using gradle and you want to publish it to bintray then this tutorial is relevant to you.

1. Create Bintray Account and Repository

Basically you just need to use maven-publish plugin provided by gradle to make it easier to publish your library. Also you can use bintray plugin if you’re going to publish it on your own bintray repository. Please make account and repository for bintray if you don’t have it. You can read Creating a New Repository in Bintray article to get started on it.

2. Create Publication Script

After we done the first step then we can start writing publication script in gradle. Below script is an example to publish your library to your bintray repository (credential was obtained in step 1).

apply plugin: 'com.jfrog.bintray'
apply plugin: 'maven-publish'
publishing {
publications {
Production(MavenPublication) {
artifact("$buildDir/outputs/aar/payment-module-release.aar")
groupId 'com.domain.sdk'
artifactId 'payment-module'
version '1.2.1'

//The publication doesn't know about our dependencies, so we have to manually add them to the pom
pom.withXml {
def dependenciesNode = asNode().appendNode('dependencies')

//Iterate over the compile dependencies (we don't want the test ones), adding a <dependency> node for each
configurations.compile.allDependencies.each {
def dependencyNode = dependenciesNode.appendNode('dependency')
dependencyNode.appendNode('groupId', it.group)
dependencyNode.appendNode('artifactId', it.name)
dependencyNode.appendNode('version', it.version)
}
}
}
Sandbox(MavenPublication) {
artifact("$buildDir/outputs/aar/corekit-development-release.aar")
groupId 'com.domain.sdk'
artifactId 'payment-module'
version '1.2.1-SANDBOX'

//The publication doesn't know about our dependencies, so we have to manually add them to the pom
pom.withXml {
def dependenciesNode = asNode().appendNode('dependencies')

//Iterate over the compile dependencies (we don't want the test ones), adding a <dependency> node for each
configurations.compile.allDependencies.each {
def dependencyNode = dependenciesNode.appendNode('dependency')
dependencyNode.appendNode('groupId', it.group)
dependencyNode.appendNode('artifactId', it.name)
dependencyNode.appendNode('version', it.version)
}
}
} }
}
bintray {
// Get Bintray credential from environment variable
user = System.getenv('BINTRAY_USER') // Get bintray User
key = System.getenv('BINTRAY_KEY') // Get bintray Secret Key
configurations = ['archives']
pkg {
repo = 'maven'
name = project.name
userOrg = 'owner-name'
licenses = ['Apache-2.0']
desc = 'Payment module SDK'
websiteUrl = "https://domain.com"
publish = true
}
publications = ['Production', 'Sandbox']

}

By looking at above script, we know that artifact, groupId, artifactId and version is needed to make a Maven publication. Note that we can make several publications within a library project. For example if our library can have several flavors such as sandbox and production build. We can make two different maven publications with same group and artifact identifier but with different version name. Sandbox one can have -SANDBOX suffix on its version.

Also in above script you will notice that there are some kind of pom related scripts. Normal implementation of maven-publish plugin will produce basic pom.xml without external dependencies needed to build our library so we need to add it manually to generated pom.xml by detecting our dependencies in our gradle script. So our library dependencies such as compile 'com.android.support:appcompat-v7:25.2.0' will be added to generated pom.xml. Users that use our library will also includes our external library without they even write it explicitly in their application gradle script.

Another things that matters when we want to publish the library in bintray was bintray part. You need to includes your credentials. To make it secure, you can add it by using environment variables. Inside pkg you can set your project details that will be shown on your bintray page. Also publications part will define your Maven publication that you want to includes on your bintray repository. In this part I set Sandbox and Production in the publications because I want to publish those variants on the bintray. Note that Sandbox and Production publications were defined in publishingpublications.

3. Run Gradle Publication Task

After completed previous steps you can start publishing your library by call specific gradle task created for bintray plugin named bintrayUpload. Please note that the task was located inside your library module (for my example it’s payment-module).

> export BINTRAY_USER=YourBintrayUsername
> export BINTRAY_KEY=YourBintraySecretKey
> ./gradlew :clean :payment-module:assembleRelease :payment-module:bintrayUpload

4. Test your Published Library

By completing third step your library now is publicly available on your bintray repository. Please make sure you have added your bintray repository name on your repositories

repositories {
maven { url "http://dl.bintray.com/owner-name/maven" }
}

Then on dependencies we can add our library definition easily.

compile 'com.domain.sdk:payment-module:1.2.1'

Start your gradle sync process and wait for your library be fetched on your project.

Notes:

  • If your library have external dependencies defined please make sure their source repository was included on repositories too.
  • If you want to use two different flavors in your project you must define the flavors in your gradle script. Example:
sandboxCompile 'com.domain.sdk:payment-module:1.2.1-SANDBOX'
productionCompile 'com.domain.sdk:payment-module:1.2.1'

That’s it from me. Hope it helps you publish your own library so it can be used by other people. Congratulations, you have contributed to community :)

--

--

Raka Westu Mogandhi
prismapp

Just an Ordinary Software Engineer that always Learn