gradlegradle-kotlin-dslspring-boot-starter

What is the right way to share subproject functionality with dependencies?


I'm working on a multimodule gradle (kts) project. Each module is a spring boot kotlin app, that provides Elasticsearch requests and responses, for example:

project
- module core
- module a
- module b
- module c
- module d

First three modules use the same common functionality from the lib: implementation("co.elastic.clients:elasticsearch-java:8.12.1"). Basically, I need to create a client that could be resued by my project modules.

The problem is that I can't create my own spring boot starter or push it to any artifactory. I'd like to create another module (e.g. module e) and import it as an implementation at other modules.

I've created that module, and successfully attached it to other dependant modules.

plugins {
    kotlin("jvm")
    kotlin("kapt")
    kotlin("plugin.spring") version "1.9.0"
    id("io.spring.dependency-management") version "1.1.3"
    id("org.springframework.boot") version "3.1.5"
}

repositories {
    mavenCentral()
    gradlePluginPortal()
}

dependencies {

    // Kotlin
    implementation("org.jetbrains.kotlin:kotlin-reflect")
    implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")

    // Starter
    implementation("org.springframework.boot:spring-boot-starter")

    // Elasticsearch
    implementation("co.elastic.clients:elasticsearch-java:8.12.1")
    implementation("org.elasticsearch:elasticsearch-geo:8.12.1")
    implementation("jakarta.json:jakarta.json-api:2.1.1")

    // Jackson
    implementation("com.fasterxml.jackson.module:jackson-module-kotlin:2.15.3")
    implementation("com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.15.3")

    // Importing common pojos
    implementation(project(":core"))

    // Logging
    implementation("io.github.microutils:kotlin-logging-jvm:3.0.5")

    testImplementation("org.springframework.boot:spring-boot-starter-test")
    testImplementation(platform("org.junit:junit-bom:5.9.1"))
    testImplementation("org.junit.jupiter:junit-jupiter")
}

tasks {

    withType<Wrapper> {
        version = "8.4"
    }

    bootJar {
        enabled = false
    }

    jar {
        enabled = true
    }

    test {
        useJUnitPlatform()
    }
}

But there is one slight problem with it. Elasticsearch dependency models are unreachable from other modules. I don't need to export all available dependencies, but is there any way to export only those for elasticsearch?


Solution

  • Elasticsearch dependency models are unreachable from other modules. I don't need to export all available dependencies, but is there any way to export only those for elasticsearch?

    The Kotlin (or Java library) plugin makes available an additional configuration api for use when writing a library module. This acts the same as the implementation configuration, except that api dependencies are also made available to consumers of the library.

    So if in Module E's build.gradle.kts file you write:

    dependencies {
        api("co.elastic.clients:elasticsearch-java:8.12.1")
    }
    

    Then any projects using Module E as a dependency will be able to use classes included in the elasticsearch-java JAR in addition to classes in Module E.