Gradle multi-module project

In a Gradle multi-module project, it's common to define shared dependencies in the parent project (root project) to avoid duplication across modules. This structure allows child modules to inherit or access those dependencies. Below are some best practices on how to correctly share dependencies between parent and child modules in a multi-module Gradle project.


Project Structure Example

multi-module-project/
├── build.gradle.kts    (Parent/root project)
├── settings.gradle.kts
├── module-a/
│   └── build.gradle.kts
├── module-b/
│   └── build.gradle.kts

Step 1: Configure settings.gradle.kts

In a multi-module project, the settings.gradle.kts file should declare all the modules that are part of the build.

// settings.gradle.kts
rootProject.name = "multi-module-project"

// Include child modules
include("module-a", "module-b")

Step 2: Define Shared Dependencies in the Parent build.gradle.kts

The root build.gradle.kts can be used to manage common dependencies for all modules. You can also add dependency management for Spring Boot or other libraries here.

// build.gradle.kts (Root Project / Parent Project)

plugins {
    `java-library` // Useful for shared libraries across modules
    id("org.springframework.boot") version "3.1.4" apply false
    id("io.spring.dependency-management") version "1.1.2"
}

allprojects {
    group = "com.example"
    version = "1.0.0"

    repositories {
        mavenCentral()
    }
}

subprojects {
    apply(plugin = "java-library")

    dependencies {
        // Shared dependencies that all modules will use
        implementation("org.springframework.boot:spring-boot-starter")
    }

    // Optional: Ensure all subprojects use the same Java version
    java {
        toolchain {
            languageVersion.set(JavaLanguageVersion.of(17)) // Java 17, for example
        }
    }
}

Explanation:

  1. allprojects {}: This block applies to both the parent and all child modules.
  2. subprojects {}: This block applies to all child modules only.
  3. Dependencies added in subprojects {}: These dependencies will be automatically available in all child modules.

Step 3: Child Module Configuration (module-a/build.gradle.kts)

In the child module, you can define only module-specific dependencies. Dependencies declared in the parent's subprojects {} block will already be available to the child modules.

// module-a/build.gradle.kts

dependencies {
    // Dependencies from the parent are already available here (e.g., Spring Boot Starter)

    // Module-specific dependencies
    implementation("com.google.guava:guava:31.1-jre")
}

Step 4: Using Dependencies from Other Modules

In a multi-module project, child modules can depend on each other. You can add a dependency on another module using the following syntax:

// module-b/build.gradle.kts

dependencies {
    // Depends on module-a
    implementation(project(":module-a"))
}

This allows module-b to use code and classes from module-a.


Step 5: Run the Build

To build the entire project, run:

./gradlew build

This command will build all modules and ensure that dependencies are resolved correctly.


Common Issues & Troubleshooting

  1. Dependency Conflicts:
    If multiple versions of the same dependency are pulled in, use the dependencyManagement plugin to control the versions.

  2. Dependencies Not Found in Child Modules:
    Make sure the subprojects block is correctly applied. If the child module is not inheriting dependencies, double-check the settings.gradle.kts to ensure the module is included.

  3. Java Version Mismatch:
    If you need all modules to use the same Java version, set the Java toolchain in the root build.gradle.kts as shown above.


Conclusion

In a Gradle multi-module project, you can manage shared dependencies efficiently by defining them in the parent project (build.gradle.kts) under the subprojects block. This way, all child modules inherit those dependencies, making the project structure cleaner and reducing duplication. You can still add module-specific dependencies in individual module build files if needed. Additionally, child modules can depend on other modules within the same project.

Let me know if you need further assistance!

댓글

이 블로그의 인기 게시물

Using the MinIO API via curl

In Kubernetes (k8s), Expose pod as NodePort

Sparse output from sparse encoder