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>

Attachment: signature.asc
Description: OpenPGP digital signature

Reply via email to