Index

Source code on github: https://github.com/kendarorg/Gradle101

003-Publishing on maven repository

First, just take the demo002 and copy as demo003

Publishin on local directory

To ease the development i choosed to use a local Maven repository to share the libraries. Again supposing our projects are in the C:\Documents directory, my new repo will be placed in C:\Documents\maven directory

This local repo will be used to overcame the need for the one level max nesting of gradle projects

The main build.gradle

In the main build.gradle i will add an external variable. This is a variable that will be seen by all build.gradle-s inside the project. This will contain a reference to the our maven directory. Please note that i assume that exists one "container" (kind of pom) project with only direct childrens! No nesting!

ext.repos = [
        'LocalMaven'   : "file://${projectDir}/../maven"
]

Then i have to tell all the subprojects to use this repository (as a source). I add this at the end of the main build.gradle. This means that all java-type subprojects will first search on the "LocalMaven" and then on the maven central.

All the subprojects will have access to the "repos" variable. The placement inside the main build.gradle is driven by the need to define a common directory for all subprojects. The internal variable will have the form of "repos.LocalMaven": notice the lack of commas!

The definition of the "jar source" repository can be placed in every java-type project, and can have the following form, the declaration order matters a lot! Here first is taken the local maven repository (just declared) and after the maven central repo.

repositories {
    maven {
        name = 'LocalMaven'
        url = uri(repos.LocalMaven)
    }
    mavenCentral()
}

The idea is to put all the repository informations in one single place to avoid littering the groovy code. We introduce some new constructs.

Inside the main build.gradle now can be added the declaration of the repos.

subprojects {
    afterEvaluate { project ->
        plugins.withType(JavaPlugin) {
            repositories {
                maven {
                    name = 'LocalMaven'
                    url = uri(repos.LocalMaven)
                }
                mavenCentral()
                ...

To demonstrate the previous statement you can add some line and see the differences (i always loved variable scoping...)

subprojects{
    println project.name
    println project.version
    afterEvaluate { project ->
        println project.name
        println project.version
        ...

gradle afterevaluate

At last i have to tell the projects that publishes artifacts to use the local maven repo. Adding the following to the previously created "subprojects" section.

subprojects {
    afterEvaluate { project ->
        plugins.withType(JavaPlugin) {
            ...
        }
        plugins.withType(MavenPublishPlugin) {
            publishing {
                publications {
                    mavenJava(MavenPublication) {
                        from project.components.java
                    }
                }
                repositories {
                    maven {
                        name = 'LocalMaven'
                        url = uri(repos.LocalMaven)
                    }
                ...

Remember to close the curly braces!!!!

Publishing the services

To publish the services on our local repository it would be enough to add the mavne-publish plugin to the build.gradle, resulting in the following. This because we already handled the publishing behaviour in the root project!

plugins {
   id 'java'
   id 'java-library'
   id 'maven-publish'
}
group 'org.kendar'
version '1.0.0-SNAPSHOT'

Now running "gradle build publish" the new directory C:\Documents\maven have been created containing the poms, md5 and jars for the services!

But this simple "publish" task... will not last long

Publishing on global repository

Setup a simple maven repository

We can now download a ready copy of Artifactory to simulate a real repo, from Artifactory Portable extract in the same dir previously used for Gradle and Java, then run partifactory.bat.

An UI will then open and the first things to do are

Integrate the main build.gradle

First must be added the variables containing the addresses of the remote repositories

ext.repos = [
        ...
        'RemoteMavenRelease'   : "http://localhost:8081/artifactory/libs-release",
        'RemoteMavenSnapshot'   : "http://localhost:8081/artifactory/libs-snapshot"
]

Now i will add the dependency on the "Remote Repo" to download files and to upload them. Here i have to add the credentials for my local artifactory repository. Of course you can work with any kind of repository following this approach.

subprojects {
    afterEvaluate { project ->
        plugins.withType(JavaPlugin) {
            repositories {
                ...
                maven {
                    name = 'RemoteMaven'
                    if (project.version.endsWith('-SNAPSHOT')) {
                        url = uri(repos.RemoteMavenSnapshot)
                    } else {
                        url = uri(repos.RemoteMavenRelease)
                    }
                    credentials {
                        username 'admin'
                        password '!Passw0rd'
                    }
                }
                ...
                mavenCentral()
            }
        }
        plugins.withType(MavenPublishPlugin) {
            publishing {
                ...
                repositories {
                    ...
                    maven {
                        name = 'RemoteMaven'
                        if (project.version.endsWith('-SNAPSHOT')) {
                            url = uri(repos.RemoteMavenSnapshot)
                        } else {
                            url = uri(repos.RemoteMavenRelease)
                        }
                        credentials {
                            username 'admin'
                            password '!Passw0rd'
                        }
                ...

A new task will then appear if we call gradle tasks: publishMavenJavaPublicationToRemoteMavenRepository (pretty long but this will be solved afterwards)

This when called will publish our data on the remote repo choosing the right path for snapshots and releases


Last modified on: February 18, 2020