Linking jcenter Android Archive (AAR) library to Maven Central Part 2

in #utopian-io6 years ago (edited)

Repository

https://github.com/aosp-mirror

Overview

In Part 1 we published our Android Archive (AAR) library to jcenter, in this tutorial we will link jcenter android aar library to maven central. After successful linking our library will be available on both jcenter and maven central.

Requirements

  • Android Studio 3.0 or higher
  • Android NDK
  • GnuPG

Difficulty

  • Intermediate

Tutorial covers

  • Android Archive (AAR) Library project
  • Requirements for maven central linking
    1. Creating maven jira ticket
    2. Repository must be linked to jcenter
    3. Generating additional artifacts
    4. Adding info in POM file
    5. Sign artifacts using GnuPG
      5.1. Creating GPG Key Pair
      5.2. Exporting public and private key
      5.3. Uploading keys to bintray
      5.4. Automatic signing artifacts
      5.5. Uploading artifacts
  • Linking to Maven Central

Guide

Android Archive (AAR) Library project

Project in this tutorial is exactly same as we created in Part 1 in this tutorial we will only change build.gradle file. In this tutorial we will create new version that will include additional artifacts and files necessary for linking to maven central.

Delete older version of library on https://bintray.com open your repository and click on version and then click on Edit

pic13.png

Scroll down and click on Delete Version button to delete this version

pic14.png

Requirements for maven central linking

Here are list of requirements for maven central linking.

1. Creating maven jira ticket

In Part 1 we created this artifact and pushed to jcenter

aar(MavenPublication) {
    groupId 'com.faob'
    artifactId archiveName
    version libVersion
    artifact("$buildDir/outputs/aar/$archiveName-release.aar")
}

groupId we used in this artifact is com.faob and groupId is usually your domain in reverse form. On of the disadvantages of maven central is that we can't use custom groupId you must own the domain but in jcenter we can use any groupId. In my case i don't own this domain faob.com so i have to change this to my project hosting domain which is github which works with maven central.

In this section we make a request to sonatype.org to assign groupId to us when we get our groupId then we can link our jcenter repo with maven central. First create account here https://issues.sonatype.org then login to your account and open dashboard. Click on create button to create issue then enter Summary, Description, Grout Id, Project URL, SCM URL and leave others as defaults then click on Create button to create issue

Summary = Publish android library
Description = I want to publish my android library to maven central
Group Id = io.github or com.github
Project URL = https://github.com/faob-dev/Tutorials
SCM URL = [email protected]:faob-dev/Tutorials.git

After few hours you will get reply something like that

io.github.faob-dev has been prepared.....

They assigned me this groupId io.github.faob-dev my github username has been appended to create unique groupId. Change groupId in build.gradle file

aar(MavenPublication) {
    groupId 'io.github.faob-dev'
    artifactId archiveName
    version libVersion
    .........
    .........
}

2. Repository must be linked to jcenter

In order to link to maven central, repository in https://bintray.com must be linked to jcenter as explained in Part 1 it should look like this

p20.png

3. Generating additional artifacts

Our package should contain jar file for sources and optional jar file for docs. To create additional jars open build.gradle file and add these line to create sources and docs jars

task sourcesJar(type: Jar) {
    classifier "sources"
    from android.sourceSets.main.java.srcDirs
}

task javadoc(type: Javadoc) {
    source = android.sourceSets.main.java.srcDirs
}

task javadocJar(type: Jar, dependsOn: javadoc) {
    classifier = 'javadoc'
    from javadoc.destinationDir
}

artifacts {
    archives javadocJar
    archives sourcesJar
}

Next step is to add those artifacts to publishing task so that those artifacts can be uploaded to https://bintray.com

publishing {
    publications {
        aar(MavenPublication) {
            groupId 'io.github.faob-dev'
            artifactId archiveName
            version libVersion

            artifact(sourcesJar)
            artifact(javadocJar)
            artifact("$buildDir/outputs/aar/$archiveName-release.aar")
        }
    }
}

4. Adding info in POM file

Maven central requires some additional information to be added in POM file which includes name, description, url, license, scm and developer. For more information please read POM example at the end in maven central Requirements. Add additional POM information in publishing task

publishing {
    publications {
        aar(MavenPublication) {
            .........
            .........
            .........
            pom.withXml {
                def root = asNode()
                root.children().last() + {
                    resolveStrategy = Closure.DELEGATE_FIRST
                    name 'AAR'
                    description 'Android aar library'
                    url 'https://github.com/faob-dev/Tutorials'
                    licenses {
                        license {
                            name 'The MIT License (MIT)'
                            url 'https://opensource.org/licenses/MIT'
                        }
                    }
                    scm {
                        url 'https://github.com/faob-dev/Tutorials'
                    }
                    developers {
                        developer {
                            name 'FaoB'
                        }
                    }
                }
            }
        }
    }
}

5. Sign artifacts using GnuPG

One of the advantages of https://bintray.com is that when we pushed our artifacts it does signing automatically. In section we will create GPG key pair and upload it to https://bintray.com and then we will enable automatic signing option to sign our artifacts automatically when we pushed our artifacts.

5.1. Creating GPG Key Pair

In this section we will create GPG key pair to sign our artifacts. Download and install GnuPG then open terminal and type this command to create new key pair

gpg --gen-key

Enter Name, Email and add some Passphrase and click on Ok to create key pair

pic2.png

After successful process key pair will be generated

pic3.png

5.2. Exporting public and private key

To export public and private key first we need KeyId to get keyId type this command

gpg --list-keys

Last eight characters of Fingerprint is KeyId see highlighted characters in screenshot my KeyId is 50C8FBFB

4.png

To export public key is ASCII format type this command value after --export is KeyId and last parameter is file name where you want to save your key

gpg --armor --export 50C8FBFB > pubkey.gpg

To export private key is ASCII format type this command value after --export-secret-keys is KeyId and last parameter is file name where you want to save your key

gpg --armor --export-secret-keys 50C8FBFB > seckey.gpg

5.3. Uploading keys to bintray

Login to https://bintray.com and click on option menu and click Edit Profile

pic5.png

Click on GPG Signing on left side menu

pic6.png

Open keys(generated in Exporting public and private key section) pubkey.gpg and seckey.gpg in your favorite text editor copy and paste pubkey in Public Key and seckey in Private Key in GPG Signing page and click Update to upload keys

pic7.png

5.4 Automatic signing artifacts

To enable automatic signing option open your repository where you want to push your artifacts and click on Edit

pic8.png

Scroll down and enable option GPG sign uploaded files using Bintray's public/private key pair and click on Update button to enable that option

pic9.png

5.5. Uploading artifacts

Open Gradle tool window in android studio and double click on

app > Tasks > build > build to create all artifacts
app > Tasks > publishing > generatePomFileForAarPublication to create POM file
app > Tasks > publishing > bintrayUpload to push all artifacts to bintray

pic15.png

After successful upload you can view files in bintray

pic16.png

As you can see all artifacts has been uploaded and all those artifacts are automatically signed with .asc extension.

Linking to Maven Central

To link our jcenter library to maven central we need Sonatype OSS credentails(token key, token pass) to get these credentials login with your sonatype account that we created in Creating maven jira ticket section https://oss.sonatype.org. Click on option menu in top right corner and click Profile

pic10.png

Select User Token from choice box

pic11.png

Click on Access User Token button and copy token key and token password

pic12.png

To link our jcenter library to maven central, open your repository on https://bintray.com and click on Maven Central tab add tokey key and token password and click on Sync button to pushed library to maven central. After successful operation you will see Sync success message on right side

pic17.png

After successful maven central sync we can see our library in this repository

pic18.png

Importing library from Maven Central

importing library from maven central is simple just add this one line to dependencies in app build.gradle file. Note dependency ends with @aar since it is aar library

dependencies {
    implementation 'io.github.faob-dev:aar:1.0.0@aar'
    ...
    ...
}

Github

Complete project available on github. Clone repo and open project name AAR just change build.gradle file here is complete file

plugins {
    id "com.jfrog.bintray" version "1.7.3"
}

apply plugin: 'com.android.library'
apply plugin: 'maven-publish'

def archiveName = 'aar'
def libVersion = '1.0.0'

android {
    compileSdkVersion 27
    defaultConfig {
        minSdkVersion 15
        targetSdkVersion 27
        archivesBaseName = archiveName
        versionCode 1
        versionName = libVersion
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
        externalNativeBuild {
            cmake {
                cppFlags ""
            }
        }
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
    externalNativeBuild {
        cmake {
            path "CMakeLists.txt"
        }
    }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'com.android.support:appcompat-v7:27.1.1'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.2'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
}

task sourcesJar(type: Jar) {
    classifier "sources"
    from android.sourceSets.main.java.srcDirs
}

task javadoc(type: Javadoc) {
    source = android.sourceSets.main.java.srcDirs
}

task javadocJar(type: Jar, dependsOn: javadoc) {
    classifier = 'javadoc'
    from javadoc.destinationDir
}

artifacts {
    archives javadocJar
    archives sourcesJar
}

Properties properties = new Properties()
properties.load(project.rootProject.file('local.properties').newDataInputStream())

bintray {
    user = properties.getProperty("bintray.user")
    key = properties.getProperty("bintray.apikey")
    pkg {
        repo = 'foo'
        name = 'libs'
        licenses = ['MIT']
        websiteUrl = 'https://github.com/faob-dev/Tutorials'
        issueTrackerUrl = 'https://github.com/faob-dev/Tutorials/issues'
        vcsUrl = 'https://github.com/faob-dev/Tutorials.git'
        version {
            name = libVersion
            vcsTag = libVersion
        }
    }
    publications = ['aar']
}

publishing {
    publications {
        aar(MavenPublication) {
            groupId 'io.github.faob-dev'
            artifactId archiveName
            version libVersion

            artifact(sourcesJar)
            artifact(javadocJar)
            artifact("$buildDir/outputs/aar/$archiveName-release.aar")

            pom.withXml {
                def root = asNode()
                root.children().last() + {
                    resolveStrategy = Closure.DELEGATE_FIRST
                    name 'AAR'
                    description 'Android aar library'
                    url 'https://github.com/faob-dev/Tutorials'
                    licenses {
                        license {
                            name 'The MIT License (MIT)'
                            url 'https://opensource.org/licenses/MIT'
                        }
                    }
                    scm {
                        url 'https://github.com/faob-dev/Tutorials'
                    }
                    developers {
                        developer {
                            name 'FaoB'
                        }
                    }
                }
            }
        }
    }
}
Sort:  

Thank you for your contribution. Its good to see tutorial like this, but you should also explain what is Maven Central and how it will benefit in the long run if you use it.

Your contribution has been evaluated according to Utopian policies and guidelines, as well as a predefined set of questions pertaining to the category.

To view those questions and the relevant answers related to your post, click here.


Need help? Write a ticket on https://support.utopian.io/.
Chat with us on Discord.
[utopian-moderator]

I am currently working on third tutorial on jitpack repository and will compare jcenter vs maven central vs jitpack. Can you tell me is this post approved or not? or i should explain pros and cons of maven central in this tutorial?

Hey @kabooom
Thanks for contributing on Utopian.
We’re already looking forward to your next contribution!

Want to chat? Join us on Discord https://discord.gg/h52nFrV.

Vote for Utopian Witness!