This message was deleted.
# plugin-development
s
This message was deleted.
v
Besides that
customRuntime
needlessly extends from
customApi
(which is already implied by depending on
customImplementation
) what is the concrete problem with that setup? The configurations look fine from a cursory look
What you probably miss are the consumable configurations with proper attributes set so that a consumer can either get what in the
java-library
plugin is
apiElements
or
runtimeElements
. And accordingly in the respectively in the
customCompile
and
customRuntime
according attributes requested, so that the intended consumable configuration is selected.
Just because you do
customImplementation(project(":internal"))
does not mean that it somehow magically depends on any of the
custom...
configurations which would not work anyway as they are not consumable. Which is probably also why you declare the dependencies on the "normal" configurations and also your custom configurations.
Here you have a graphic on how the
java-library
configurations are wired together: https://docs.gradle.org/current/userguide/java_library_plugin.html#sec:java_library_configurations_graph
And here you can read more about variant selection: https://docs.gradle.org/current/userguide/variant_model.html
p
Yes, I have read the documentation on variant selection, and also have read the source code for the JavaLibraryPlugin and JavaBasePlugin.
In the exercise project I have published, this is the dependency report on
customCompile
and `compileClasspath`:
Copy code
compileClasspath - Compile classpath for source set 'main'.
\--- project :intermediate
     \--- project :base

customCompile - custom compile dependencies
\--- project :intermediate
     +--- project :base
     \--- project :internal
I understand that outgoing artifacts must be configured on consumable configurations for things to work out. I have simple code which is capable of resolving artifacts in direct dependencies. But I cannot so far understand how to set up the distinct behaviours of "api" and "implementation".
I will fix the redundant
extendsFrom
to reduce the noise.
v
Within one project, the difference between
compileClasspath
and
runtimeClasspath
is only that in the former
compileOnly
is included and in the latter
runtimeOnly
. But
api
and
implementation
are included in both as you can see at the graphic I linked you to.
In downstream projects, the consumable configurations are used, so
apiElements
which does not contain
implementation
vs.
runtimeElements
which contains both.
Those two consumable configurations have different attributes set, specifically
org.gradle.usage
which is set to
java-api
vs.
java-runtime
.
The downstream projects then accordingly request this attribute, depending on whether it is used for compiling, or for running, so
compileClasspath
requests this attribute to be
java-api
while
runtimeClasspath
requests this attribute to be
java-runtime
.
p
The distinction between "api" and "implementation" is made by attributes, then?
v
No, the distinction between
apiElements
and
runtimeElements
, which are the consumable configurations. And there the former just extends
api
while the latter extends
implementation
and thus also
api
implicitly. So in the long run, yes.
p
Thanks! I am familiar with using attributes. I'll try to work this out and see how far I can get on my own.
👌 1
v
You can also see from
./gradlew application:dependencyInsight --dependency :intermediate --configuration customCompile
which variant was selected and from
./gradlew intermediate:outgoingVariants
you can see the published variants.
p
Yes, adding a usage-like attribute to the exercise did the trick. I have updated the repository with my result. Thank you very much!
👌 1