adriangl1997
adriangl1997

Reputation: 67

What is a proper way to include runtime classpath in compile classpath in Gradle?

I have a following Gradle project structure:

project-root/
├── adapters/
│   ├── adapter1/
│   │   ├── main
│   │   └── test
│   ├── adapter2/
│   │   ├── main
│   │   └── test
│   └── adapter3/
│       ├── main
│       └── test
└── app-spring-boot/
    ├── main
    ├── test
    └── integrationTest

In the app-spring-boot module, the adapters are included only as runtime dependency:

// project-root/app-spring-boot/build.gradle.kts
dependencies {
    runtimeOnly(project(":adapters:adapter1")
    runtimeOnly(project(":adapters:adapter2")
    runtimeOnly(project(":adapters:adapter3")
}

In the app-spring-boot module for integrationTest source set, I would like to be able to access all dependencies at compile time not only directly from app-spring-boot, but from all of the included :adapters projects as well.

I've used following configuration:

// project-root/app-spring-boot/build.gradle.kts
plugins {
    `jvm-test-suite`
}

testing {
    suites {
        val test by getting(JvmTestSuite::class)

        val integrationTest by registering(JvmTestSuite::class) {
            useJUnitJupiter()
            dependencies {
                implementation(project())
            }
            sources {
                compileClasspath += sourceSets.main.get().runtimeClasspath
            }
        }
    }
}

compileClasspath += sourceSets.main.get().runtimeClasspath does the trick and all dependencies from included runtimeOnly projects are accessible at compile time, but I'm wondering what it is the correct and idiomatic Gradle way of doing it, especially since I saw @chalimartines comment.

Upvotes: 1

Views: 1637

Answers (1)

Bjørn Vester
Bjørn Vester

Reputation: 7598

I agree with the comment you found, saying that adding to the compile classpath is not the right way as you end up with duplicated dependencies.

When applying the test suites plugin, it will create a set of configurations similar to the ones from the main and test source sets, prefixed with the name of the test suite. Because your test suite is called integrationTest, the "implementation" configuration is named integrationTestImplementation.

With this, you can add the runtime dependencies to the compile classpath by making this implementation configuration of the test suite extend the regular runtimeClasspath configuration from the main source set. E.g.:

testing {
    // ...
}

configurations["integrationTestImplementation"].extendsFrom(configurations["runtimeClasspath"])

Upvotes: 1

Related Questions