This message was deleted.
# community-support
s
This message was deleted.
v
You cannot use an ARQ for resolving normal artifacts. They are only for POM, source artifact and javadoc artifact. And even for that they are discouraged, as they are not variant / attribute aware. The only reason they are not deprecated or removed afaik is, because there is no adequate replacement yet. For resolving artifacts, you would just use normal configurations or artifact views that you resolve.
e
Thanks, I'm using ARQ as described here. I ended up solving it by creating the filename using the maven standard of
artifactId-version.packaging
v
Still not getting it. If you want normal artifact, why do you use ARQ at all and not a configuration? And if you calculate the filename as you just said, what would that help for? It wouldn't mean that artifact is available somewhere on disk.
e
I primarily need the POM. I also was going to use the default artifact to help me build the download URL for it (i.e. use the filename of the artifact).
@Vampire do you happen to know how Gradle itself figures out where the normal artifact is for a given dependency? Do they derive it the same way I did from the POM, or is there another way to do it? Or if you know generally where in the Gradle codebase this happens can you point me there and I'll go looking myself?
v
Heavily depends. If you have Gradle Module Metadata, it contains the file names for the respective variants. If you have a POM, I think it is just derived by name and version from the artifact coordinates. If you have ivy.xml, afair the same.
But where this is in code, no idea would have to search myself
e
Thanks!
👌 1
Can anyone from Gradle (or anyone who knows) point me in the direction of where in the codebase the default artifact is determined from a POM?
a
Is there an example of a variant published to maven central that produces different files per variant? Eli and I are trying to figure out something for sbom generation and I can't seem to wrap my head around how variants exist on maven central. Is it still one aar/jar? And variant information is embedded in the module file? Or does gradle write multiple files to the repository with different extension that a variant can reference? Will there be separate poms per variant?
I'm mostly looking for an example that is published to maven central currently that has multiple variants and multiple files if this is a possibility
v
Don't know an example from the top of my head, but i can tell you.
Different variants are the same POM, they are different variants of the same artifact, so same coordinates.
For Maven, so in POM, dependencies that are only on "other" variants but not on the main variant are
optional
dependencies, variants with other artifacts are artifacts with a classifier with the variant name.
You can have variants that have the same artifact but only different dependencies, you can have variants that have a different artifact but the same dependencies, you can have variants with different dependencies and different artifact.
Properly modeled and conveniently usable the variants are mainly when you are a Gradle consumer and the Gradle Module Metadata is used.
In that the feature variants are properly modeled, with exactly defining which variants needs which dependencies and which variant has which artifact.
So if you depend on a feature variant from Gradle, you automatically get the correct artifact and the correct dependencies.
From a non GMM-compatible consumer like Maven, you would need to manually depend on the needed optional dependencies if applicable and use a classifier for the artifact manually.
a
you can have variants that have a different artifact but the same dependencies, you can have variants with different dependencies and different artifact
This is the part I'm not clear on
v
Ask me 🙂
a
does that mean for some maven central repo
x/y/z/artifact.jar
there also exists
x/y/z/artifact-typeB.jar
?
which I mean central may not allow
how is it structured?
or
x/y/z/artifact.typeB.jar
I feel like we might do this wrong without understanding variants completely
and I have zero experience with variants
v
does that mean for some maven central repo
x/y/z/artifact.jar
there also exists
x/y/z/artifact-typeB.jar
?
Yes, and Maven Central allows that. That are just jars with classifiers like they are used even before Gradle. Just Gradle modeled the feature variants properly in the Gradle Module Metadata.
a
oh right
-sources
-javadoc
v
Well, those are not feature variants, but basically yes, the same
a
sorry I mean yeah I forgot about those
soo, the ARQ result will give us the correct POM for the variant and we can use that to infer a correct file reference?
so I might need to also embed variant information in the sbom, cause the artifact coordinates could point to anything?
dev.test:test:1.0.0
is not a narrow enough reference
also, can a gradle project include multiple variants of the same artifact?
can I depend on
test
and
test-typeB
?
via some crazy shenanigans
v
"correct POM for the variant" is questionable. There are no different POMs. POMs are not able to model variants
a
so there is no
x/y/z/artifact-typeB.pom
?
v
You have one POM and that is only for the "main" variant, with additional dependencies for other variants marked as "optional" in them
No, there is not
a
oh I see
v
And artifact resolution queries also are neither attribute nor variant aware
Which is also the main reason it is very questionable to use them
The only reason they are not deprecated or removed is, because there is not yet an adequate replacement that is variant aware
a
I mean we only want poms to obtain metadata about a project, not dependency information
we get dependency information from the gradle system
v
If you need proper information about feature variants, you need to read the Gradle Module Metadata
And yes, a project can depend on multiple feature variants of another library
a
okay, thanks this was super helpful
v
Well, it depends on how the feature variants are declared
They can be declared in a way that all or also just some are mutually exclusive, or they can be compatible to be used together
An example:
You can have a library "framework-x". This library can have a feature variant for oracle database support and a feature variant for mssql database support and a feature variant for e-mail support
The two database support feature variants could be declared to be mutually exclusive, but you can depend on the main feature variant, additionally on one of the database feature variants and additionally on the e-mail feature variant, depending on which features you need in your project.
a
how do you represent this in a
build.gradle(.kts)
?
I think I may have found the docs
e
So it seems like even without variants we'd potentially run into trouble with ARQ because from just the POM we have no way of knowing if the user depends on an artifact with a specific classifier?
a
I think we can still use the POM to infer some metadata like "organization" or "developer"
but artifact file resolution should come from gradle (although I wonder if we might have component ID clashes)
e
E.g. a library has a main artifact for java-8 and supplies a classifier for java-11. The consumer specifies the java-11 classifier, but since all we get from ARQ is the POM, we don't know which artifact is getting downloaded, and so we can't properly build the SBOM
a
do variants all share a single componentID (super class at least)?
e
I think we can still use the POM to infer some metadata like "organization" or "developer"
Right we can use the POM for other information, but it's not reliable for determining the main artifact that is depended on.
👍 1
v
do variants all share a single componentID (super class at least)?
I'm not sure what exactly you mean with "componentID"
a
yeah that was a bit vague
v
how do you represent this in a
build.gradle(.kts)
?
Can be very differently. You can identify feature variants by just using attributes. For example there could be a Gradle plugin variant for Gradle 7 and one for Gradle 8+. The dependency is just on the coordinates. Gradle sets the attribute that defines the Gradle version and thus automatically gets the appropriate feature variant. Or feature variants can be an explicit thing, like in the above example "give me oracle database support variant", then you typically specify that by requesting a certain capability.
v
And you could of course also just say "give me the artifact with classifier X", but that's bad practice. 😄
👍 1
ComponentId was this object
As all feature variants are under the same coordinates, yes, the component id should be the same, or at least equal
a
gotcha
v
And additionally, a consumer build can even use component metadata rules to freely modify the existing feature variants of a dependency to fix faulty or add missing metadata.
For example all the javafx libraries are published with several classifiers, one per platform as the contain platform specific native libraries. But the javafx libraries do not publish Gradle Module Metadata, so the artifacts with classifiers are simply present.
a
yeah, I think gradle's regular resolution mechanism gives us the full tree correctly. I'm worried that we're not handling the case where two variants are on the tree, pointing to two different files, but are keyed using the same ComponentIdentifier in our
Map<ComponentIdentifier, File>
v
But if you for example apply the JavaFX Gradle plugin 0.1.0 or newer, it registers a component metadata rule that properly defines feature variants for those classified artifacts, so that you can resolve them properly variant-aware.
a
we wont be using ARQ for dependency resolution now, just for pom/parent-pom and effective-pom generation (purely for metadata)
👌 1
again, this was super helpful, thanks so much!
v
You're welcome 🙂