Hi, I want to create a gradle project structure wi...
# gradle
f
Hi, I want to create a gradle project structure with 2 additional sourceSets, that both should be accessible by my main source set. I added source sets and added new source set’s outputs to the main runtime and compile classpaths
Copy code
sourceSets {
    val port by creating {}

    val adapter by creating {
        runtimeClasspath += port.output
        compileClasspath += port.output
    }
    main {
        runtimeClasspath += port.output
        compileClasspath += port.output

        runtimeClasspath += adapter.output
        compileClasspath += adapter.output
    }
}
I also made changes to the configurations:
Copy code
configurations {
    val portImplementation by getting {}
    val portRuntimeOnly by getting {}

    val adapterImplementation by getting {
        extendsFrom(portImplementation)
    }
    val adapterRuntimeOnly by getting {
        extendsFrom(portRuntimeOnly)
    }

    implementation {
        extendsFrom(portImplementation)
        extendsFrom(adapterImplementation)
    }
    runtimeOnly {
        extendsFrom(portRuntimeOnly)
        extendsFrom(adapterRuntimeOnly)
    }
}
IntelliJ is able to compile and run the project (no unresolved references, runs by
run
gradle task from application plugin), but when creating or running a fat jar (
runShadow
from application plugin or
runFatJar
from ktor plugin) i get
java.lang.ClassNotFoundException
for classes from
adapter
or
port
source sets. How to link the source sets properly for running app’s fatJar?
a
I guess you need to add the new configurations to the packaging tasks - there’s a similar example in the Gradle docs https://docs.gradle.org/current/userguide/working_with_files.html#sec:creating_uber_jar_example
you might want to try feature variants. I’m not sure if it 100% fits what you need, but it will set up a lot more of the plumbing with regards to configurations https://docs.gradle.org/current/userguide/feature_variants.html
probably the simplest and most robust solution in terms of Gradle config is just to have multiple Gradle subprojects!
Copy code
.
├── my-project/
│   ├── feature1-adapter/
│   │   └── build.gradle.kts
│   ├── feature1-core/
│   │   └── build.gradle.kts
│   └── feature1-port/
│       └── build.gradle.kts
├── setttings.gradle.kts
└── build.gradle.kts
f
@Adam S i know about subprojects but i want to leverage kotlin internal access modifier which works only for gradle source sets. Also, the source sets i created logically are for one project (port - domain, adapter - infra/tech stuf, main - main function and “plugging” adapters to ports. In the future I might want to add suprojects and I will want each of them to have such source sets
a
it would be nice if
internal
was a bit more granular. As an alternative some projects use a
@RequiresOptIn
annotation https://kotlinlang.org/docs/opt-in-requirements.html#opt-in-to-using-api
f
I went with your first suggestion and it seems to work after adding
Copy code
tasks.named<ShadowJar>("shadowJar") {
    from(sourceSets["adapter"].output, sourceSets["port"].output)
}