# Java Modules Sample

version 6.5-milestone-1

- Groovy DSL

- Kotlin DSL

| You can open this sample inside an IDE using the IntelliJ’s Gradle import or Eclipse Buildship.

This sample shows how to create a multi-project containing Java Modules. Java Modules are a feature of Java itself, available since Java 9, that allows for better encapsulation.

In Gradle, each source set containing Java sources can be turned into a module by adding a `module-info.java` file. Typically, in a project with Java Modules like this one, the main source set of a subproject represents a module.

    src
    └── main
        └── java
            └── module-info.java

In the `module-info.java` file you define dependencies to other modules using keywords like `requires` or `requires transitive`. These correspond to the `implementation` and `api` dependencies defined in the Gradle build file. In addition, a module `exports` packages that should be visible to consumers. Other packages are not visible outside of the module.

    module org.gradle.sample.utilities {
        requires transitive org.gradle.sample.list;
        exports org.gradle.sample.utilities;
    }

Unit (whitebox) tests that need to access the internals of a module can be written in the traditional way by not adding a `module-info.java` to the test source set. In test execution, the modules are then treated as standard Java libraries with the encapsulation deactivated.

Blackbox (e.g. integration) tests, which should also follow the encapsulation rules during test execution, can be written by turning the corresponding test sources set itself into a module by adding a `module-info.java`. This is shown in this extended sample.

As of Gradle 6.4, module support needs to be explicitly activated, which we do for all subprojects in the root build script like this:

build.gradle

        plugins.withType(JavaPlugin).configureEach {
            java {
                modularity.inferModulePath = true
            }
        }

build.gradle.kts

        plugins.withType<JavaPlugin>().configureEach {
            configure<JavaPluginExtension> {
                modularity.inferModulePath.set(true)
            }
        }

For more information, see Java Module support in the Java Library Plugin, Java Module support in the Application Plugin and testing Java Modules.