[
https://jira.codehaus.org/browse/MNG-5652?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=351715#comment-351715
]
Robert Scholte commented on MNG-5652:
-------------------------------------
{quote}The exact name is still undecided. Some candidate names are: "supplies",
"provides", and "proffers"{quote}
I think the concept is easier to understand in we stay closer to the MANIFEST
entries, i.e {{implementation}} vs. {{specification}}
> "supplies"/"provides"/"proffers" concept proposal
> -------------------------------------------------
>
> Key: MNG-5652
> URL: https://jira.codehaus.org/browse/MNG-5652
> Project: Maven
> Issue Type: New Feature
> Components: FDPFC
> Reporter: Stephen Connolly
>
> The exact name is still undecided. Some candidate names are: "supplies",
> "provides", and "proffers"
> h2. "supplies" concept proposal
> ===========================
> h3. Introduction
> ------------
> The following is a proposal for Maven in a post-modelVersion-4.0.0 era. The
> aim of this proposal is to simplify the management of dependency trees in the
> decentralised era of artifact production that we find ourselves in.
> The core issue is that different organisations can produce artifacts that may
> overlap. The easiest example is the servlet-api. If we restrict ourselves to
> version 2.5 of the servlet specification there are quite a few artifacts that
> all deliver the exact same content:
> * {{jetty:servlet-api:2.5-6.0.2}}
> * {{org.daisy.libs:servlet-api:2.5.0}}
> * {{org.mortbay.jetty:servlet-api-2.5:6.1.14}}
> * {{org.jboss.spec.javax.servlet:jboss-servlet-api_2.5_spec:1.0.1.Final}}
> * etc
> **Note:** this is a generic problem that is not restricted to the
> servlet-api, the servlet-api just provides the example that will be most
> familiar to everyone.
> So where these multiple artifacts supplying the equivalent content becomes a
> problem is when the dependency tree is being calculated. If you have two
> dependencies each declaring transitive dependencies on different artifacts
> that supply equivalent content, then you end up with two copies of the same
> JAR file in your classpath.
> In the case of the servlet-api, the hack most people use is to declare the
> servlet-api with scope `provided` thus preventing it from being transitive.
> This is, however, a hack. In a more ideal world it would be better to let the
> servlet-api be transitive and only when we get to the WAR module would we
> declare that a specific servlet-api is to be provided in the containers that
> the WAR is targets for deployment into.
> We can take a second example that does not have the luxury of a *de facto*
> hack.
> * {{javax.faces:jsf-api:2.1}}
> * {{org.jboss.spec.javax.faces:jboss-jsf-api_2.1_spec:2.1.28.Final}}
> * {{org.apache.myfaces.core:myfaces-api:2.1.13}}
> Now in the case of the JSF API, you are supposed to bundle the JSF API in
> your WAR file. So if I use three JSF component libraries, I could very well
> end up with three different but equivalent JSF API jars in my WAR file.
> Ideally what we want is some way of telling Maven that these artifacts are
> equivalent.
> Proposal
> --------
> Introduce the concept of "supplies" to the project model. The concept needs
> three changes to the project model:
> 1. An explicit top level construct for a project to explicitly declare
> up-front artifacts that it knows - at the time the project is being authored
> - to contain equivalent content to at least a subset of the project's
> content. Declarations could include a claim from: `subset`, `superset`,
> `disjoint` and `equivalent` with the default being `disjoint`.
> 2. An explicit sub-element of the `dependency` construct to allow consumers
> to *post-facto* declare a specific dependency as supplying equivalent content
> for other dependencies
> 3. An extension to the `dependency/excludes/exclude` construct to allow
> consumers to remove claims a dependency makes with respect to supplying
> equivalent content
> By way of illustration, here are some examples of these constructs mapped to
> a Model Version 4.0.0 like XML schema. As the post-modelVersion-4.0.0 schema
> is not yet known, this represents the best way to illustrate how the concept
> will work, but note that this proposal does not suggest a schema for this
> concept.
> h3. Example 1
> This illustrates how we would want, say, the `myfaces-api` project model to
> look.
> {code:xml}
> <project>
> <groupId>org.apache.myfaces.core</groupId>
> <artifactId>myfaces-api</artifactId>
> <version>2.1.3</version>
> ...
> <supplyManagement>
> <supplies>
> <groupId>javax.faces</groupId>
> <artifactId>jsf-api</artifactId>
> <version>[2.1,2.2)</version>
> <claim>superset</claim>
> <supplies>
> <supplies>
> <groupId>org.jboss.spec.javax.faces</groupId>
> <artifactId>jboss-jsf-api_2.1_spec</artifactId>
> <claim>equivalent</claim>
> <supplies>
> </supplyManagement>
> ...
> </project>
> {code}
> This indicates that the {{myfaces-api}} artifact is intended to be useable as
> a drop-in replacement for either the {{javax.faces:jsf-api}} artifact within
> a bounded range or for any version of the
> {{org.jboss.spec.javax.faces:jboss-jsf-api_2.1_spec}} artifact. If you get a
> supplier conflict in your classpath, then Maven should fail the build.
> For example if somebody forked {{myfaces-api}} but did not list
> {{myfaces-api}} in the fork's supplyManagement and you end up with both
> {{myfaces-api}} and {{myfaces-fork-api}} in your classpath. Maven can detect
> that there are two dependencies that both claim to supply
> {{javax.faces:jsf-api}} and fail the build, thereby letting the user add
> either exclusions or additional supplies information to one of the artifacts
> and preventing duplicate artifacts on the classpath. The build need not be
> failed if the supplies claims provide a resolution. e.g. if the claim is
> {{equivalent}} then that implies that there is a 1:1 mapping and hence the
> artifacts are drop-in replacements. However where the claim is {{superset}}
> we cannot know that the extra content in our artifact is the same as the
> extra content in another artifact which has a superset of
> `javax.faces:jsf-api`.
> h3. Example 2
> This illustrates a JSF component library that is working with the existing
> JSF APIs
> {code:xml}
> <project>
> ...
> <dependencies>
> <dependency>
> <groupId>javax.faces</groupId>
> <artifactId>jsf-api</artifactId>
> <version>2.1</version>
> <supplyManagement>
> <supplies>
> <groupId>org.jboss.spec.javax.faces</groupId>
> <artifactId>jboss-jsf-api_2.1_spec</artifactId>
> <claim>equivalent</claim>
> <supplies>
> <supplies>
> <groupId>org.apache.myfaces.core</groupId>
> <artifactId>myfaces-api</artifactId>
> <version>[2.1,2.2)</version>
> <claim>equivalent</claim>
> </supplies>
> </supplyManagement>
> <dependency>
> </dependencies>
> ...
> </project>
> {code}
> In this case we are publishing a transitive dependency with additional
> supplyManagement injected. Consumers of this project would thus gain the
> benefit of collapsing their transitive dependencies for any of these three
> artifacts. As all artifacts are declared with `equivalent` claim, thus the
> nearest of those three artifacts to the project will win as per the standard
> dependency resolution rules when dealing with conflicting version
> requirements in the transitive dependency tree.
> h3. Example 3
> Finally, there is the case where you need to correct an incorrect claim of
> supply
> {code:xml}
> <project>
> ...
> <dependencies>
> <dependency>
> <groupId>javax.faces</groupId>
> <artifactId>jsf-api</artifactId>
> <version>2.1</version>
> <exclusions>
> <exclusion>
> <groupId>org.jboss.spec.javax.faces</groupId>
> <artifactId>jboss-jsf-api_2.2_spec</artifactId>
> <scope>supplies</scope>
> <exclusion>
> </exclusions>
> <dependency>
> </dependencies>
> ...
> </project>
> {code}
> This would typically be coupled with adding back in a correct supplies
> definition, but we need to allow for people to correct the graph after the
> fact of their dependencies being deployed to the remote repository.
> h3. Claim conflict resolution
> The four classes of claim can be resolved using the following matrix
> | | | A | A | A | A
> |
> | | | subset | equivalent | superset | disjoint |
> | B | subset | conflict | A wins | A wins | conflict |
> | B | equivalent | B wins | A or B | A wins | conflict |
> | B | superset | B wins | B wins | conflict | conflict |
> | B | disjoint | conflict | conflict | conflict | conflict |
> The default unspecified claim is {{disjoint}} which indicates that some of
> the content is reproduced, but not all and there is additional content added.
> With such a claim there will always be conflict and the build should fail
> until the Project Model is updated to either remove some of the claims or
> resolve the dependency clash.
> The ideal claim is {{equivalent}} which indicates that the two artifacts are
> bi-directionally substitutable. This does not mean that the contents are
> identical. It does mean that they both deliver on the same contract in an
> equivalent fashion.
> The {{subset}}` and {{superset}} claims are for aggregation APIs. So for
> example the Java EE Web Profile API is a superset of the various spec APIs
> that make up the Java EE Web Profile and a subset of the full Java EE
> specification. The use of the {{subset}}` claim should be reserved to those
> cases that are strict subsets. If anything is added that is not in the
> supplied artifact then the correct claim is {{disjoint}}.
> h3. Validation of supplies claims
> We do not want to introduce Java bias with this feature. As a result the
> validation of claims and supplies directives will be left to plugins. For the
> Java case we should probably provide either/both an enforcer rule or a maven
> hosted plugin to assist in checking JAR projects against the declared
> supplies declarations, but Maven core should not be concerned with solving
> the validation problem.
> Similarly, while there may be advantages in a more fine grained API contract
> negotiation between dependencies, to bind such a concept into the project
> model would significantly taint the Maven project model with more
> Java-centric concepts. Given that current software development typically uses
> at least two core languages: Java and JavaScript, we should be aiming to
> reduce Java-centric constructs from Maven rather than increase them.
> h3. Backporting
> It will not be possible to fully express this concept in a modelVersion 4.0.0
> project model. Thus if generating 4.0.0 compatible project models, the aim
> should be to fully resolve the dependencies of the project using all
> available information and express that as the transitive dependencies.
> Thus we will not expose the "supplies" information to modelVersion 4.0.0
> parsers but we will expose the end results of that and present the final
> effective flattened dependency tree.
> modelVersion 4.0.0 consumers will thus be no worse off than they already are
> and those consumers understanding newer modelVersions can get the enhanced
> tree resolution that they would not get otherwise.
--
This message was sent by Atlassian JIRA
(v6.1.6#6162)