maven-artifact-transfer: How to build the classpath for arbitrary GAVs?

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

maven-artifact-transfer: How to build the classpath for arbitrary GAVs?

Andreas Sewe-2
Hi,

I am currently struggling with the maven-artifact-transfer 0.9.1 API.
Here's what I am trying to accomplish: Given an arbitrary GAV and a
scope (compile or test), construct the compile- or test-scoped flat
classpath for that GAV.

DependencyResolver seems to be the class I am after, but I haven't found
 out whether to use the Dependency-based or DependableCoordinate-based
overload of resolveDependencies (the Model-based overload won't work, as
I have just a GAV and no Model for it). Also, I haven't figured out how
to specify the scope I am after (dependency:build-classpath doesn't use
maven-artifact-transfer but rather get its information out of the
current project's Model).

And pointers are greatly appreciated.

Best wishes,

Andreas


signature.asc (836 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: maven-artifact-transfer: How to build the classpath for arbitrary GAVs?

Robert Scholte-8
Hi Andreas,

DependencyResolver is indeed the correct class to use.
Any of the overloaded methods will do: When you have the dependecy, you  
can use it directly.
In other cases use DependableCoordinate, which represents an instance that  
can contain dependencies.
That can either be a MavenProject, Dependency or Plugin.

To control the scope you need to specify a filter, in your case the  
ScopeFilter[1]

This should be the information you were looking for,
Robert

[1]  
https://maven.apache.org/shared/maven-common-artifact-filters/apidocs/org/apache/maven/shared/artifact/filter/resolve/ScopeFilter.html

On Mon, 20 Nov 2017 17:08:19 +0100, Andreas Sewe  
<[hidden email]> wrote:

> Hi,
>
> I am currently struggling with the maven-artifact-transfer 0.9.1 API.
> Here's what I am trying to accomplish: Given an arbitrary GAV and a
> scope (compile or test), construct the compile- or test-scoped flat
> classpath for that GAV.
>
> DependencyResolver seems to be the class I am after, but I haven't found
>  out whether to use the Dependency-based or DependableCoordinate-based
> overload of resolveDependencies (the Model-based overload won't work, as
> I have just a GAV and no Model for it). Also, I haven't figured out how
> to specify the scope I am after (dependency:build-classpath doesn't use
> maven-artifact-transfer but rather get its information out of the
> current project's Model).
>
> And pointers are greatly appreciated.
>
> Best wishes,
>
> Andreas

---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

Re: maven-artifact-transfer: How to build the classpath for arbitrary GAVs?

Andreas Sewe-2
Hi Robert,

thank you for the pointer.

> This should be the information you were looking for,

Alas, the information doesn't quite solve my problems -- but maybe I'm
just being obtuse.

Let's say I want to built (and resolve) the test-scoped classpath of
org.apache.maven.shared:maven-artifact-transfer:0.9.1. All I have is
this coordinate.

What I do:

  DefaultDependableCoordinate coord = new DefaultDependableCoordinate();
  coord.setGroupId("org.apache.maven.shared");
  coord.setGroupId("maven-artifact-transfer");
  coord.setVersion("0.9.1");
  dependencyResolver.resolveDependencies(
    session.getProjectBuildingRequest(), coord, null);

This gives the following list of artifacts (sorted, to allow for better
comparison):

> commons-codec:commons-codec:jar:1.6
> commons-io:commons-io:jar:2.5
> org.apache.maven.shared:maven-artifact-transfer:jar:0.9.1
> org.apache.maven.shared:maven-common-artifact-filters:jar:3.0.1
> org.apache.maven.shared:maven-shared-utils:jar:3.1.0
> org.apache.maven:maven-aether-provider:jar:3.0
> org.apache.maven:maven-artifact:jar:3.0
> org.apache.maven:maven-core:jar:3.0
> org.apache.maven:maven-model-builder:jar:3.0
> org.apache.maven:maven-model:jar:3.0
> org.apache.maven:maven-plugin-api:jar:3.0
> org.apache.maven:maven-repository-metadata:jar:3.0
> org.apache.maven:maven-settings-builder:jar:3.0
> org.apache.maven:maven-settings:jar:3.0
> org.codehaus.plexus:plexus-classworlds:jar:2.2.3
> org.codehaus.plexus:plexus-component-annotations:jar:1.7.1
> org.codehaus.plexus:plexus-interpolation:jar:1.14
> org.codehaus.plexus:plexus-utils:jar:3.0.24
> org.slf4j:slf4j-api:jar:1.7.5
> org.sonatype.aether:aether-api:jar:1.7
> org.sonatype.aether:aether-impl:jar:1.7
> org.sonatype.aether:aether-spi:jar:1.7
> org.sonatype.aether:aether-util:jar:1.7
> org.sonatype.plexus:plexus-cipher:jar:1.4
> org.sonatype.plexus:plexus-sec-dispatcher:jar:1.3
> org.sonatype.sisu:sisu-guice:jar:noaop:2.1.7
> org.sonatype.sisu:sisu-inject-bean:jar:1.4.2
> org.sonatype.sisu:sisu-inject-plexus:jar:1.4.2
This differs quite a bit from what "mvn dependency:list" outputs when
run on a SVN checkout of the maven-artifact-transfer project:

> commons-codec:commons-codec:jar:1.6:compile
> commons-io:commons-io:jar:2.5:compile
> junit:junit:jar:4.11:test
> org.apache.maven.shared:maven-common-artifact-filters:jar:3.0.1:compile
> org.apache.maven.shared:maven-shared-utils:jar:3.1.0:compile
> org.apache.maven:maven-aether-provider:jar:3.0:runtime
> org.apache.maven:maven-artifact:jar:3.0:compile
> org.apache.maven:maven-core:jar:3.0:compile
> org.apache.maven:maven-model-builder:jar:3.0:compile
> org.apache.maven:maven-model:jar:3.0:compile
> org.apache.maven:maven-plugin-api:jar:3.0:compile
> org.apache.maven:maven-repository-metadata:jar:3.0:compile
> org.apache.maven:maven-settings-builder:jar:3.0:compile
> org.apache.maven:maven-settings:jar:3.0:compile
> org.codehaus.plexus:plexus-classworlds:jar:2.2.3:compile
> org.codehaus.plexus:plexus-component-annotations:jar:1.7.1:compile
> org.codehaus.plexus:plexus-interpolation:jar:1.14:compile
> org.codehaus.plexus:plexus-utils:jar:3.0.24:compile
> org.eclipse.aether:aether-api:jar:0.9.0.M2:provided
> org.eclipse.aether:aether-impl:jar:0.9.0.M2:provided
> org.eclipse.aether:aether-spi:jar:0.9.0.M2:provided
> org.eclipse.aether:aether-util:jar:0.9.0.M2:compile
> org.hamcrest:hamcrest-core:jar:1.3:test
> org.slf4j:slf4j-api:jar:1.7.5:compile
> org.sonatype.aether:aether-api:jar:1.7:provided
> org.sonatype.aether:aether-impl:jar:1.7:test
> org.sonatype.aether:aether-spi:jar:1.7:test
> org.sonatype.aether:aether-util:jar:1.7:provided
> org.sonatype.plexus:plexus-cipher:jar:1.4:compile
> org.sonatype.plexus:plexus-sec-dispatcher:jar:1.3:compile
> org.sonatype.sisu:sisu-guice:jar:noaop:2.1.7:compile
> org.sonatype.sisu:sisu-inject-bean:jar:1.4.2:compile
> org.sonatype.sisu:sisu-inject-plexus:jar:1.4.2:compile
The list returned by resolveDependencies contains
maven-artifact-transfer (fine), but lacks *some* test-scoped
dependencies (like junit:junit:4.11), while others like
org.sonatype.aether:aether-impl:1.7 are included. However, a lot of
provided-scoped dependency (org.eclipse.aether) are missing, but some
are present (org.sonatype.aether).

Can you explain to me what's going on here? I feel like I am missing an
important conceptual bit.

In a similar vein, can you enlighten me what the "type" of a
DependableCoordinate is? In particular, how does it differ from the
extension or packaging?

Best wishes,

Andreas


signature.asc (836 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: maven-artifact-transfer: How to build the classpath for arbitrary GAVs?

Robert Scholte-8
Hi Andreas,

have a look at
https://maven.apache.org/shared/maven-artifact-transfer/comparison.html
that should explain the difference between type/package/file-extension

If it is still not clear enough, please help imrpove the documentation.  
There's a reason why it is not yet a 1.0.0.

I can't explain why you only get a subset of the dependencies.
It looks like only the compile+runtime dependencies are selected.

There should be no specific logic for this in maven-artifact-transfer,  
since this project is meant to be only a bridge to any Aether  
implementation.

thanks,
Robert

On Tue, 21 Nov 2017 15:28:43 +0100, Andreas Sewe  
<[hidden email]> wrote:

> Hi Robert,
>
> thank you for the pointer.
>
>> This should be the information you were looking for,
>
> Alas, the information doesn't quite solve my problems -- but maybe I'm
> just being obtuse.
>
> Let's say I want to built (and resolve) the test-scoped classpath of
> org.apache.maven.shared:maven-artifact-transfer:0.9.1. All I have is
> this coordinate.
>
> What I do:
>
>   DefaultDependableCoordinate coord = new DefaultDependableCoordinate();
>   coord.setGroupId("org.apache.maven.shared");
>   coord.setGroupId("maven-artifact-transfer");
>   coord.setVersion("0.9.1");
>   dependencyResolver.resolveDependencies(
>     session.getProjectBuildingRequest(), coord, null);
>
> This gives the following list of artifacts (sorted, to allow for better
> comparison):
>
>> commons-codec:commons-codec:jar:1.6
>> commons-io:commons-io:jar:2.5
>> org.apache.maven.shared:maven-artifact-transfer:jar:0.9.1
>> org.apache.maven.shared:maven-common-artifact-filters:jar:3.0.1
>> org.apache.maven.shared:maven-shared-utils:jar:3.1.0
>> org.apache.maven:maven-aether-provider:jar:3.0
>> org.apache.maven:maven-artifact:jar:3.0
>> org.apache.maven:maven-core:jar:3.0
>> org.apache.maven:maven-model-builder:jar:3.0
>> org.apache.maven:maven-model:jar:3.0
>> org.apache.maven:maven-plugin-api:jar:3.0
>> org.apache.maven:maven-repository-metadata:jar:3.0
>> org.apache.maven:maven-settings-builder:jar:3.0
>> org.apache.maven:maven-settings:jar:3.0
>> org.codehaus.plexus:plexus-classworlds:jar:2.2.3
>> org.codehaus.plexus:plexus-component-annotations:jar:1.7.1
>> org.codehaus.plexus:plexus-interpolation:jar:1.14
>> org.codehaus.plexus:plexus-utils:jar:3.0.24
>> org.slf4j:slf4j-api:jar:1.7.5
>> org.sonatype.aether:aether-api:jar:1.7
>> org.sonatype.aether:aether-impl:jar:1.7
>> org.sonatype.aether:aether-spi:jar:1.7
>> org.sonatype.aether:aether-util:jar:1.7
>> org.sonatype.plexus:plexus-cipher:jar:1.4
>> org.sonatype.plexus:plexus-sec-dispatcher:jar:1.3
>> org.sonatype.sisu:sisu-guice:jar:noaop:2.1.7
>> org.sonatype.sisu:sisu-inject-bean:jar:1.4.2
>> org.sonatype.sisu:sisu-inject-plexus:jar:1.4.2
>
> This differs quite a bit from what "mvn dependency:list" outputs when
> run on a SVN checkout of the maven-artifact-transfer project:
>
>> commons-codec:commons-codec:jar:1.6:compile
>> commons-io:commons-io:jar:2.5:compile
>> junit:junit:jar:4.11:test
>> org.apache.maven.shared:maven-common-artifact-filters:jar:3.0.1:compile
>> org.apache.maven.shared:maven-shared-utils:jar:3.1.0:compile
>> org.apache.maven:maven-aether-provider:jar:3.0:runtime
>> org.apache.maven:maven-artifact:jar:3.0:compile
>> org.apache.maven:maven-core:jar:3.0:compile
>> org.apache.maven:maven-model-builder:jar:3.0:compile
>> org.apache.maven:maven-model:jar:3.0:compile
>> org.apache.maven:maven-plugin-api:jar:3.0:compile
>> org.apache.maven:maven-repository-metadata:jar:3.0:compile
>> org.apache.maven:maven-settings-builder:jar:3.0:compile
>> org.apache.maven:maven-settings:jar:3.0:compile
>> org.codehaus.plexus:plexus-classworlds:jar:2.2.3:compile
>> org.codehaus.plexus:plexus-component-annotations:jar:1.7.1:compile
>> org.codehaus.plexus:plexus-interpolation:jar:1.14:compile
>> org.codehaus.plexus:plexus-utils:jar:3.0.24:compile
>> org.eclipse.aether:aether-api:jar:0.9.0.M2:provided
>> org.eclipse.aether:aether-impl:jar:0.9.0.M2:provided
>> org.eclipse.aether:aether-spi:jar:0.9.0.M2:provided
>> org.eclipse.aether:aether-util:jar:0.9.0.M2:compile
>> org.hamcrest:hamcrest-core:jar:1.3:test
>> org.slf4j:slf4j-api:jar:1.7.5:compile
>> org.sonatype.aether:aether-api:jar:1.7:provided
>> org.sonatype.aether:aether-impl:jar:1.7:test
>> org.sonatype.aether:aether-spi:jar:1.7:test
>> org.sonatype.aether:aether-util:jar:1.7:provided
>> org.sonatype.plexus:plexus-cipher:jar:1.4:compile
>> org.sonatype.plexus:plexus-sec-dispatcher:jar:1.3:compile
>> org.sonatype.sisu:sisu-guice:jar:noaop:2.1.7:compile
>> org.sonatype.sisu:sisu-inject-bean:jar:1.4.2:compile
>> org.sonatype.sisu:sisu-inject-plexus:jar:1.4.2:compile
>
> The list returned by resolveDependencies contains
> maven-artifact-transfer (fine), but lacks *some* test-scoped
> dependencies (like junit:junit:4.11), while others like
> org.sonatype.aether:aether-impl:1.7 are included. However, a lot of
> provided-scoped dependency (org.eclipse.aether) are missing, but some
> are present (org.sonatype.aether).
>
> Can you explain to me what's going on here? I feel like I am missing an
> important conceptual bit.
>
> In a similar vein, can you enlighten me what the "type" of a
> DependableCoordinate is? In particular, how does it differ from the
> extension or packaging?
>
> Best wishes,
>
> Andreas

---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

Re: maven-artifact-transfer: How to build the classpath for arbitrary GAVs?

Andreas Sewe-2
Hi Robert,

> have a look at
> https://maven.apache.org/shared/maven-artifact-transfer/comparison.html
> that should explain the difference between type/package/file-extension
>
> If it is still not clear enough, please help imrpove the documentation.

One way to improve the documentation is to show what Packages these
types come from (the type Artifact is not exactly unique in Maven-land).

It would also help if these concepts (Dependency, Artifact,
MavenProject) could be related to their Artifact Transfer
"counterparts": ArtifactCoordinate and DependableCoordinate, which I
assume are meant as thin abstractions over the concepts from Maven core
-- although I am not sure.

> I can't explain why you only get a subset of the dependencies.
> It looks like only the compile+runtime dependencies are selected.

Yes, stepping through the actual resolver implementation I found that
the DefaultDependencyCollector gets a DependencySelector from the
current RepositorySession. And that selector excludes the "test" and
"provided" scopes.

So using my own ScopeFilter doesn't matter, as it is only used during
the "resolve" step of resolveDependencies. But the test- and provided
scoped dependencies don't make it that far; they are filtered out during
the "collect dependencies" step by the *session's* DependencySelector.

(AFAICT, there's no way to customize the RepositorySession used by
maven-artifact-transfer, right?)

> There should be no specific logic for this in maven-artifact-transfer,
> since this project is meant to be only a bridge to any Aether
> implementation.

I know have a working Aether based implementation which doesn't even
need to change the DependencySelector, thanks to an explicit
ArtifactDescriptorRequest.

Here's the gist:

  ArtifactDescriptorRequest descriptorRequest = new
      ArtifactDescriptorRequest();
  descriptorRequest.setArtifact(artifact);
  ArtifactDescriptorResult descriptorResult =
      system.readArtifactDescriptor(session, descriptorRequest);

  CollectRequest collectRequest = new CollectRequest();
  collectRequest.setRootArtifact(descriptorResult.getArtifact());
  collectRequest.setDependencies(descriptorResult.getDependencies());
  collectRequest.setManagedDependencies(
      descriptorResult.getManagedDependencies());
               
  DependencyFilter filter =
      DependencyFilterUtils.classpathFilter(JavaScopes.TEST);
  DependencyRequest dependencyRequest =
      new DependencyRequest(collectRequest, filter);
  system.resolveDependencies(session, dependencyRequest);

The key bit seems to be the explicit CollectRequest.setDependencies
call. If I construct the CollectRequest with a single root dependency
instead...

  CollectRequest collectRequest =
      new CollectRequest(new Dependency(artifact, "test"), repos);

...then my final list of resolved dependencies contains the artifact
itself but *not* its test-scoped dependencies. The problem seems to be
that we are "off by one level" in the dependency graph. As my root
artifact is itself already a Dependency, its test-scoped dependencies
are excluded per the normal scoping rules for *transitive* dependencies
[1]. And test-scoped transitive dependencies are never included.

Hope this makes sense.

As to what it means for maven-artifact-transfer: If you really want to
support this use case (I'm fine with limiting myself to new Maven
Resolver versions; I don't have to use the facade), then you need to
support artifact descriptor requests as well. I could then use the
four-argument version of DependencyResolver.resolveDependencies.

Best wishes,

Andreas

[1]
<https://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html#Dependency_Scope>


signature.asc (836 bytes) Download Attachment