Hello Guillaume

Le 2024-08-07 à 22 h 23, Guillaume Nodet a écrit :

  * 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

It would be great to have this summary in the package-info Javadoc, and also the relevant parts in each interface Javadoc. I will try to do a PR next weekend for 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.

I agree about immutability, but "immutable" does not necessarily mean "no deferred computation". The JDK has some examples of immutable objects that compute and cache their values when first requested (e.g., `Path` itself, or `BigDecimal`, `Class`, etc.). Users still have the benefit of immutable objects, in the sense that they can share the same instance without the need for defensive copies and without the need to do synchronization themselves. So maybe a `Dependency.getModuleDescription()` method could load the module description when first needed, and `Dependency` still be considered immutable as long as no visible state changed. That method would potentially throw IOException, but again there is examples in the JDK of immutable objects throwing exceptions (e.g. File.getCanonicalPath()).


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.

That would work. But isn't `ResolvedDependency` the same as `Dependency` if we accept deferred computation, including for downloading the JAR file?


About `Dependency` as a specialization of `DependencyCoordinate`:

I find the outcome much less clear. The same kind of objects are used for multiple things, and it's very confusing.

Alternatively we can keep the interfaces independent but nevertheless resolve the method collisions as below:

 * In DependencyCoordinate, rename getVersion() as getVersionConstraint().
 * Choose a common name and return type for `isOptional()`.

It would allow an implementation class, if desired, to implement the two interfaces even if from user's eyes they are still two separated types. This strategy allows to implement the `toCoordinate()` method simply as `return this`, thus avoiding a copy operation and the possible information lost that come with it. Implementations are not forced to do that, it just become possible when convenient.

    Martin

Reply via email to