4

My project uses several Gradle source sets for its production code base instead of just main:

  • domain
  • dal
  • rest
  • test
  • dbUnitTest

This has proven very useful for limiting dependencies and enforcing separation of concern.

It comes with one downside however: we cannot access classes or methods with visibility internal from within test classes. The reason for this is that the Kotlin compiler places every source set in its own "module":

$ find . -name '*.kotlin_module'
./classes/kotlin/domain/META-INF/contact-management_domain.kotlin_module
./classes/kotlin/dal/META-INF/contact-management_dal.kotlin_module
./classes/kotlin/rest/META-INF/contact-management_dal.kotlin_module
./classes/kotlin/test/META-INF/contact-management.kotlin_module
./classes/kotlin/dbUnitTest/META-INF/contact-management_dbUnitTest.kotlin_module

I would like all sourceset to use the same module name "contact-management", as the main sourceset would by default.

I tried to override the name with the compiler option -module-name:

tasks.withType<KotlinCompile> {
    kotlinOptions {
        // place all source sets in the same kotlin module, making objects with 'internal' visibility available to every source sets of this project
        freeCompilerArgs += listOf("-module-name \"contact-management\")
    }
}

Upon running gradlew build, I get

> Task :contact-management:compileDomainKotlin FAILED
e: Invalid argument: -module-name "contact-management"

The reason being that -module-name "contact-management_domain" is set before by the Gradle code invoking the Kotlin compiler as well, but apparently this option is only accepted once.

In a Gradle build, how can I control what is being considered "one module" by the Kotlin compiler?

A related question where the test source set is to be split has no satisfactory answers so far.

blubb
  • 8,562
  • 2
  • 36
  • 67

0 Answers0