Good morning, I'm currently trying to resolve a pr...
# community-support
d
Good morning, I'm currently trying to resolve a project's dependencies in a detachedConfiguration. My goal is to determine what dependencies are currently being exposed as
api
declared dependencies without digging into the buildscript, but instead referring to the resolution. I understand this won't be foolproof. The issue I'm having is that when I try to resolve the current project in a detachedConfiguration, it either fails to resolve, or it doesn't show any exposed dependencies, despite having a
api
dependency on
gson
.
Copy code
def detached = project.configurations.detachedConfiguration()
def dep = project.dependencies.project(path: ":${project.path}", configuration: detached)
detached.dependencies.add(dep)
v
Without seeing the error you get, this is mostly guesswork, but I guess the problem is, that you do not set the necessary attributes on your configuration so that the dependencies can be resolved properly. Do you really need that programmatically? If not, it is much easier to either use a build
--scan
, or the
dependencies
task. If this is about investigating whether your dependencies are declared in the "correct" configurations, I recommend using the https://github.com/autonomousapps/dependency-analysis-gradle-plugin
👀 1
d
Yeah. I'd like a programmatic way. I've reviewed this project many times, sadly though it doesn't support the version of Java we use here, and last I knew, there was no plan for backwards support in this plugin.
v
You mean you use a version of Java older than 11?
☝️ 1
This is only about the version used to run Gradle actually. So you could for example use JVM toolchains to decouple the version used to run Gradle from the version used to compile and run your code.
d
🤔 So we could technically run Gradle in Java 11 while continuing to build our product in a lower version?
v
Exactly, that's what JVM toolchains are for
🙌 1
d
Would the idea here be to set the default toolchain to JDK 11, then configure our CompileJava tasks to use the lower version? Is there an approach that we could make the default our lower and then specify Gradle's (basically the vice-versa)? I was looking at that page, but I only see an approach that handles the default to 11.
v
No, the toolchain you define is what you need for your project code (instead of setting things like
release
,
sourceCompatibility
, or
targetCompatibility
). For the Java 11, you just ensure that you run Gradle with Java 11. In Gradle 8.8 is a new incubating feature that you can indeed also use a discovered toolchain for running Gradle.
👍 1
d
Ah, gotcha. Sounds good. Reason I was asking is to try to 'prefer' our lower version since our CI server doesn't currently support 11 afaik. But I guess whatever java default is set up there will be picked, but I doubt we'll want to push this plugin into our buildscripts.
As long as it's not committed, we won't have any issue building the same way as before - or at least that's the hope, lol. Appreciate the info about toolchains though! I'll fiddle around with it
I don't know if we'll be able to push for that sort of change in our developer environments, though - having two versions of JDK installed. That specific error I'm getting is a ModuleVersionResolveException, where it says:
Copy code
A dependency was declared on configuration 'configuration ':myProject:detachedConfiguration1'' which is not declared in the descriptor for project :myProject.
So in my first example, I used the
detached.name
as the the configuration for the dependency which seems to resolve now, the only issue is that it seems to be circularly showing up as a dependency when debugging the dependency. Basically the `resolutionResult`'s
dependencies
has my project reference, but it's dependencies (
ResolvedDependencyResult.dependencies
) only lists itself.
It looks like the
dep
object I created in the first code block I sent is considered transitive too... so I'm unsure why this wouldn't provide all of the compile dependencies required.
v
The "configuration: detached" in your original snippet is wrong. You ask "give me the configuration with name 'myProjectdetachedConfiguration1' from the project" and the error is telling you of course that a configuration with that name does not exist. Remove the "configuration: detached".
d
Removing that brings back the resolution error - I've redacted my project name, but the gray blocks represent
:myProject
The detailMessage is null on the Exception... but the message is just a generic 'Could not resolve project' - I guess this could just be the fact that it's trying to resolve itself?
v
Maybe you cannot depend on the project from a detached configuration. It is detached. 🤷‍♂️ Never tried such a thing
But I also don't know why you want to do that at all. Just resolve the
compileClasspath
configuration for example.
d
That's what I was trying at first, but I couldn't find anything in the Gradle API that denoted a dependency being an exposed
api
dependency while debugging. I don't see anything that would represent that, but I know sometimes my debugger doesn't report all available objects for some reason.
Well, not sure why I didn't just check this configuration, but I see your point against compileClasspath now.
Copy code
api - API dependencies for the 'main' feature. (n)
\--- com.google.code.gson:gson:2.7 (n)
v
api
is not a resolvable configuration, so you cannot directly resolve it. If you want to know what is only in
api
or the configurations it extends, you probably have to add a new resolvable configuration that only extends from
api
and has the necessary attributes set.
Or if you only want the declared configurations, there is also a way I think, but I don't know it from the top of my head
I would really suggest you use the dependency analysis plugin, that will save you quite some trouble and give concrete advices what to move where.
d
I have it working now, and I guess I technically don't need to know what dependencies are being resolved when a dependency is declared under the
api
configuration, rather I just need to know what dependencies are declared in the
api
configuration. This became much more trivial:
Copy code
project.configurations.named(JavaPlugin.API_CONFIGURATION_NAME).get().dependencies
👌 1
As for the dependency analysis plugin, we'll be migrating to that at a later date when we can, but for now we already have an implementation that provides some reporting we'll need for a holistic view of our dependency 'situation' we have :)
👌 1
v
Btw. once you migrated to it, it exposes also its analysis results and intermediate results afair, so you can also use the information from it for some custom visualization.