Is there a proper way to handle dynamic dependency...
# community-support
m
Is there a proper way to handle dynamic dependency resolution depending on the task being run? I'm looking for something like a lazy configuration that only tries to resolve its dependencies when a task or source set is used. I would also take something like a try/catch in dependency resolution, if something like that is possible.
v
Can you elaborate on your use-case? If a task only uses configuration X, configuration Y will never be resolved if not something else uses it.
m
I have a source set with dependencies that fail (intended). This source set is extended by a few other source sets, each of which has an associated task to run something in these sources. compileJava seems to trigger the dependency resolution, even though the source set I'm trying compile doesn't use the source set with absent dependencies
I've put the dependencies directly in the source set block as well, and I'm not sure if that's best practice or not.
v
I'm actually not sure I understand correctly, can you maybe knit an MCVE that shows your situation?
m
Sure, give me a moment.
In my root project:
Copy code
sourceSets {
val A: SourceSet by creating {
  dependencies {
    implementation(X)
  }
  [additional sources]
}
And in my subproject:
Copy code
sourceSets{
val demoConfig: SourceSet by creating {
  java {
    srcDir("examples/robots")
    include(listOf("demo.java"))

    compileClasspath += rootProject.sourceSets.getByName("A").output + rootProject.sourceSets.getByName("A").compileClasspath
    runtimeClasspath += rootProject.sourceSets.getByName("A").output + rootProject.sourceSets.getByName("A").runtimeClasspath
  }
}
}

tasks.register<JavaExec>("run-demo") {
  classpath = project.sourceSets.getByName("demoConfig").runtimeClasspath + sourceSets.getByName("demoConfig").output
  workingDir = rootDir
  mainClass = "examples.robots.Demo"

}
tasks.getByName("compileDemoConfigJava").dependsOn("compileAJava")
I want to be able to run-demo if I have the appropriate files, but the project shouldn't require dependency X
The issue is with running some task other than run-demo, which tries to pull in dependency X
I realize that the dependency block in the source set is incorrect, this is probably the third or fourth iteration of this I've tried.
v
Exactly, having it in there is just visual clutter, it is the same as having it top-level. You want to get
implementationConfigurationName
from
A
, get the configuration with that name, and declare the dependencies there
But also, you really really really should not reach into the root project model from the subproject model to get something
Really not
m
I'll set up the cross project builds correctly soon, thanks for the link! In the meantime, is something like this the proper way to add a dependency to the source set?
Copy code
dependencies {
  configurations.getByName("AImplementation")([depend])
}
These dependencies resolve but don't seem to be in the classpath, which leads me to believe I'm doing something wrong. But adding the AImplementation classpath to A feels wrong as well.
Ah nevermind, I resolved that issue. Thanks so much for all your help!
Having trouble finding how to add them as an API dependency instead, AApi and AApiElements don't seem to be created by the java plugin
v
Exactly. These are added by the
java-library
plugin. That's almost all it does actually
m
So would the proper way to add these as an API to create a new configuration, add the API depends, and add that to A's classpath instead of using AImplementation directly? Or is there some AApi config auto generated by java-library that I'm not seeing?
v
Yes, if you apply
java-library
, you will automatically get
aApi
m
Thought so, but "AImplementation" is created and exists and "AApi" is not
v
Can you show an MCVE?