Build only subprojects in a dynamic multi-module project

Hello guys,

Sorry for the vague question, but I have a bad feeling that I’m doing something wrong.

There is a root project that contains a huge number of subprojects. Each subproject is a trivial Java sample with source code, tests, and documentation. At the same time, the root project doesn’t have any source code by itself only subfolders and build artifacts. Due to the high number of samples and their simplicity was decided not to create build.gradle.kts for each of them, instead include them dynamically by writing script in the parent settings.gradle.kts.

Here is how build.gradle.kts and settings.gradle.kts looks like:

build.gradle.kts

plugins {
    java.apply
}

subprojects {
    apply(plugin = "java")

    sourceSets {
        main {
            java {
                srcDir("main")
            }
        }
        test {
            java {
                srcDir("test")
            }
        }
    }

    repositories {
        mavenCentral()
    }

    dependencies {
        testImplementation("org.junit.jupiter", "junit-jupiter", "5.6.0")
    }

    tasks {
        test {
            useJUnitPlatform()
        }
    }
}

settings.gradle.kts

rootProject.name = "all-samples"

File(rootDir, "samples").walk().filter {
  it.isDirectory && File(it, "main").isDirectory
}.forEach {
  include(it.name)
  project(":${it.name}").projectDir = it
}

Project structure:

root
├── docs
├── gradle
├── samples
|   ├── sampleA
|   |   ├── main
|   |   └── test
|   ├── sampleB
|   |   ├── main
|   |   └── test
|   └── [... many more]
...
├── build.gradle.kts
├── settings.gradle.kts
...

Finally the question :upside_down_face:: when I build the project as ./gradlew build I see that compileJava task for the root project shows NO-SOURCE. Which basically means that Gradle executed Java plugin task to the root project didn’t find any sources and moved to its subprojects.

Q1. Is it possible to run a Java plugin task for subprojects only without listing all their names?
Q2. Or somehow exclude Java-related tasks from execution against the root projects?

> Task :compileJava NO-SOURCE
> Task :classes
> Task :compileTestJava NO-SOURCE
> Task :testClasses
> Task :test NO-SOURCE
> Task :sampleA:compileJava UP-TO-DATE
> Task :sampleA:classes
> Task :sampleB:compileJava UP-TO-DATE
> Task :sampleB:classes

P.S. I’ve tried java.apply(false) but got the error:

Plugin ‘org.gradle.java’ is a core Gradle plugin, which is already on the classpath. Requesting it with the ‘apply false’ option is a no-op.

Any help is highly appreciated.

Found the same issue described here: https://github.com/gradle/kotlin-dsl-samples/issues/916
But, the resolution is not quite clear to me. Do we have another way to accomplish this?

For the record: to exclude compileJava task from rootProject I use the -x :compileJava
Example:

./gradlew compileJava -x :compileJava

> Task :sampleA:compileJava UP-TO-DATE
> Task :sampleA:classes
> Task :sampleB:compileJava UP-TO-DATE
> Task :sampleB:classes

If you find a better way of doing this, please let me know.