How best to resolve a configuration as compileClasspath does?


I have noticed that Gradle’s compileClasspath configuration does not resolve as other configurations do. In my case, I had added some project dependencies to the compileOnly configuration and observed that compileClasspath only contained the projects’ “API elements”. Which was fine, of course. However, when I added the exact same project dependencies (and nothing else) to a configuration I had created myself, Gradle resolved all of their “runtime elements” instead.

After digging into the JavaPlugin code, I discovered that I could add the following attributes to my configuration:

attribute(CATEGORY_ATTRIBUTE, project.getObjects().named(Category.class, LIBRARY))
attribute(USAGE_ATTRIBUTE, project.getObjects().named(Usage.class, JAVA_API))

which performed the :sparkles: Gradle Magic :sparkles: that I needed.

The Category and Usage classes don’t appear to be “internal” to Gradle, but is this really the cleanest way to create a configuration that resolves like compileClasspath please? I had never even heard of these classes before now, and feel like I’ve crossed some kind of threshold and entered “Dragon Territory”.

What have I done? Should I retreat, and if so, to where?

Thanks for any advice here,

You are encountering Gradle’s variant aware dependency resolution.

Thanks for replying :+1:. I suppose knowing the Dragon’s name at least means that I am doing something that is officially supported. However, I still cannot really claim to understand precisely which aspects of Gradle’s functionality these attributes affect:

attribute(BUNDLING_ATTRIBUTE, objects.named(Bundling.class, EXTERNAL))
attribute(CATEGORY_ATTRIBUTE, objects.named(Category.class, LIBRARY))
attribute(USAGE_ATTRIBUTE, objects.named(Usage.class, JAVA_API))

I suspect I may only need USAGE_ATTRIBUTE for my problem really. However, I think I’ll feed all 3 princesses to the Dragon anyway, just to be safe.