Hi,
I’m building a multi-repo multi-project Java app and I ran into an issue with properly collapsing source sets. I know one possible answer is- “don’t collapse, keep them as separate subprojects”. I’m trying to understand if there is a solution that involves collapsing.
In repo A, subproject A1, I have source sets: base
, generator
, generated
, and main
, with the following relevant bits:
dependencies {
generatorImplementation sourceSets.base.output
generatedImplementation sourceSets.base.output
api sourceSets.base.output
api sourceSets.generated.output
}
jar {
from sourceSets.base.output
from sourceSets.generated.output
}
What I’m trying to achieve is to compile the 3 source sets (base
, generated
, main
) independently, run the generator in the 4th (generator
) source set, and package everything up in a single jar.
Above, I use api
instead of implementation
because the latter generates IDE (not Gradle!) errors in a composite build. Concretely, I have a second repo B, with its own subproject B2, which has A:A1 as implementation
dependency. I usually build A & B as a composite build, so that during the compilation of B, A’s products are replaced by Gradle instead of looking into a repo. If I replace api
by implementation
above, the IDE starts showing errors in B2 files because (to the best of my understanding…) while replacing artifacts, it ends up using A1’s main
source set build products (classes) only instead of A1’s jar, and the IDE thinks the A1 generated
source set build products are runtimeOnly
dependencies. What I find strange is that only the IDE (IntelliJ) is confused about this, Gradle compiles B2 just fine, even with implementation
instead of api
.
However, I have another problem, which is the topic of this post: I have another subproject B:Bdist which is a distribution, declaring B:B2 as implementation
dependency. When I assemble B:Bdist from a composite build, Gradle ends up packaging A1 generated
source set class files inside the distribution zip, instead of packaging the A1 jar, I assume because of how the artifact replacing works. If I publish A:A1 to Maven local and build B separately, the dist zip looks fine, containing only the A1 jar.
TLDR Question- Is there a way to tell Gradle in a composite build to build and use the A1 jar from build/libs
instead of sifting through build/classes/java/main
while ignoring (at least when it is wrapped by the IDE…) build/classes/java/generated
?
Non-TLDR Question- Can you think of a way to fix this, while keeping the source set collapsing and the composite build?
Thanks!