Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Publishing of a modular library to Maven using Gradle

Suppose I'm using Gradle for a modular library development. In my root project I have subprojects geometry, algorithms, visualizer, and I'd like to publish a jar artifact of each.

As for now in my root build.gradle I have the following part:

apply plugin: 'maven-publish'
publishing {
    publications {
        publishDemos(MavenPublication) {
            groupId 'ru.ifmo.ctddev.igushkin.cg'
            artifactId 'geometry'
            version globalVersion
            artifact project(':geometry').tasks.getByName('jar')
        }
        publishAlgorithms(MavenPublication) {
            groupId 'ru.ifmo.ctddev.igushkin.cg'
            artifactId 'algorithms'
            version globalVersion
            artifact project(':algorithms').tasks.getByName('jar')
        }
        publishVisualizer(MavenPublication) {
            groupId 'ru.ifmo.ctddev.igushkin.cg'
            artifactId 'visualizer'
            version globalVersion
            artifact project(':visualizer').tasks.getByName('jar')
        }
    }
}

My first question: is there a shorter way of describing the publications? For example, I'd like to state that for each subproject I need a publication with the artifactId set from its name.


Next, my subprojects depend on each other, both algorithms and visualizer depend on classes from geometry, but at this point the jars do not contain the dependencies, and, for example, the user will have to add dependencies to both geometry and algorithms if they want to use algorithms.

So, is there a way for to provide some sort of auto-dependency, so that adding algorithms would also add geometry? If yes, how do I do it? If no, what is the idiomatic way of providing modular libraries? Should I assemble jars with dependencies instead?

UPD: Am I right that instead of artifact ... I should just use from project(':...').components.java, because it will pick up both artifacts and dependencies? How do I pick dependencies separately if I use artifact ...?

like image 615
hotkey Avatar asked Feb 02 '16 01:02

hotkey


People also ask

How do I migrate from Gradle to Maven?

To convert Gradle to Maven, first, Maven plugin need to be added in the build. gradle file. Then, simply run Gradle install in the directory. Lastly, simply run gradle install and the directory containing build.


1 Answers

You can do less verbose publication declaration by injecting the same publication config into each subproject. For example for a multi-build project with the structure:

ROOT
│   build.gradle
│   settings.gradle
├───subA
│       build.gradle
│
├───subB
│       build.gradle
│
└───subC
        build.gradle

In your root build.gradle, you can do:

apply plugin:'maven-publish'

subprojects{
    publishing {
        publications {
            "$project.name"(MavenPublication) {
                groupId project.group
                artifactId project.name
                version project.version
                from components.java
            }
        }
    }
}

Each subproject defines its own groupid and version like so:

group = 'org.test.sample.A'
version = '1.0'

The artifactId is picked up from the subproject name. Running gradle publish results in a repo of this structure:

org
└───test
    └───sample
        ├───A
        │   └───subA
        │       └───1.0
        │               subA-1.0.jar
        │               subA-1.0.pom
        ├───B
        │   └───subB
        │       └───1.0
        │               subB-1.0.jar
        │               subB-1.0.pom
        └───C
            └───subC
                └───1.0
                        subC-1.0.jar
                        subC-1.0.pom

Dependencies

This config also automatically takes care of dependencies. For instance if in subproject subA you had:

dependencies{
    compile project(':subB')
}

Since I am using from components.java instead of artifact, the plugin knows to look for dependencies and generates a pom for subA that includes:

  <dependencies>
    <dependency>
      <groupId>org.gradle.sample.B</groupId>
      <artifactId>subB</artifactId>
      <version>1.0</version>
      <scope>runtime</scope>
    </dependency>
  </dependencies>
like image 133
RaGe Avatar answered Oct 12 '22 01:10

RaGe