Le lun. 5 août 2024 à 14:07, Martin Desruisseaux <martin.desruisse...@geomatys.com> a écrit : > > Maven 4 has two very similar public interfaces for dependencies: > > * Dependency > * DependencyCoordinate > > They both have groupId, artifactId, classifier, version, extension, type > and scope. Differences that I observed are: > > * Spelling: `Dependency.isOptional()` versus > `DependencyCoordinate.getOptional()`.
Right, though `Dependency.isOptional()` is of type `boolean`, while `DependencyCoordinate.getOptional()` is of type `Boolean` (it is nullable). > * Return type of the `getVersion()` method: `Version` versus > `VersionConstraint`. Yes, that's expected. > * Methods present only in `DependencyCoordinate`: > o getExclusions() > * Methods present only in `Dependency`: > o getBaseVersion() > o isSnapshot() > o toCoordinate() > > The Javadoc does not explain those differences, neither why they exist. > I suspect that `DependencyCoordinate` is the dependency has declared in > the POM, while `Dependency` is the dependency effectively used after > resolution. For example, with the range of versions > (`VersionConstraint`) resolved to a single version (`Version`). Is that > right? If so, would it make sense to add a `getPath()` method in > `Dependency` since it has been resolved? I think it would make the API > easier to understand compared to the current approach of using > `Map<Dependency, Path>` returned by `DependencyResolverResult`. We have ArtifactCoordinate, Artifact, DependencyCoordinate and Dependency in the main API. We also have the org.apache.maven.api.model.Dependency which is the object deserialised from the POM. That one is used to create DependencyCoordinate so that they can be resolved. Back to the 4 objects: - ArtifactCoordinate are used to locate artifacts in a repository, it's basically a pointer to a file in maven repository - Artifact is the pointed artifact in the repository. They are created when *resolving* an ArtifactCoordinate which basically download the artifact in the local repository - DependencyCoordinate is used to express a dependency - Node is the main output of the *dependency collection* process, it's the graph of dependencies - Dependency is the output of the *collection* process, part of the graph computed from one or more DependencyCoordinate, it's an artifact + type + scope The main reason was to remove some ambiguities between the various states that we have in the resolver API for Artifact and Dependency. They may or may not have a resolved version (i.e. be an actual pointer), may or may not be present in the local repository. You can't really use a non resolved Artifact for a resolved one, but the resolver api does not provide any difference between those. So, ArtifactCoordinate and DependencyCoordinate have a VersionRange, while Artifact and Dependency have their version resolved. > The reason why I ask is because there is path-derived information that > need to be associated to a dependency, in particular `ModuleDescriptor`. > With the current design, those information are provided by > `DependencyResolverResult`. It would be more natural to have them in > `Dependency`. I.e., instead of: > > * DependencyResolverResult > o Map<Dependency, Path> getDependencies() > o Optional<ModuleDescriptor> getModuleModuleDescriptor(Path) > o Optional<String> getModuleName(Path) > > We could have: > > * DependencyResolverResult > o Set<Dependency> getDependencies() > * Dependency > o Path getPath() > o Optional<ModuleDescriptor> getModuleModuleDescriptor() > o Optional<String> Dependency.getModuleName() > > The choice would determine the form of pull request #1625, which is > needed for the new compiler plugin and will also be needed by at least > javadoc, surefire and exec plugins. The Path for a given Artifact can be retrieved using the `ArtifactManager`, that was done to be similar to the `ProjectManager`. So the main problem is that one of the core design decision of the API was to have immutable objects. We could have a `ResolvedDependency` which would inherit from `Dependency` and provide a `getPath()` method. Same for `Artifact`, where we could define a `ResolvedArtifact`. Or maybe add a `Resolved` interface with the `getPath` method, which could be implemented by both ResolvedArtifact and ResolvedDependency. The `collect` The collected graph contains Node and Dependency, while the resolved dependencies are... resolved. Which means that when building the collected graph, the artifacts are not downloaded, only the POMs are needed to build the graph. When will those getModuleDescriptor() and getModuleName() methods be made available ? I'd like to keep the objects immutable though. > As a side note, do we really need those interfaces to be independent? > Couldn't we define Dependency as a subtype of DependencyCoordinate > together with Artifact as a subtype of ArtifactCoordinate? It would > remove the need for `toCoordinate()` methods and reduce a little bit the > amount of wrappings between different kinds of objects in Maven core, > which cost me hours of debugging (pull request #1621 is small, but was > hard to find). I find the outcome much less clear. The same kind of objects are used for multiple things, and it's very confusing. > > Martin > -- ------------------------ Guillaume Nodet --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@maven.apache.org For additional commands, e-mail: dev-h...@maven.apache.org