...
The artifacts element consists of details of all the artifacts produced by the project. The artifacts are partitioned by platformId.
Code Block | ||
---|---|---|
| ||
<artifacts [platformId="..."]> <artifact .../> </artifacts> |
...
The artifact element consists of the details of a specific artifact produced by the project.
Code Block | ||
---|---|---|
| ||
<artifact type="..." [classifier="..."]> <information .../> <license .../> <component .../> <provides .../> <requires .../> <supports .../> </artifact> |
...
The component element consists of hints to the consumer of type specific components that are present within the artifact for consideration during conflict resolution.
Code Block | ||
---|---|---|
| ||
<component id="..."/> |
There is one mandatory element:
...
The provides element indicates that this artifact embeds equivalent content to the named dependency
Code Block | ||
---|---|---|
| ||
<provides groupId="..." artifactId="..." |
...
[platformId="..."] [version="..."] range="..." type="..." |
...
[classifier="...]/> |
The following are mandatory elements
...
The requires element indicates a mandatory transitive dependency.
...
Code Block | ||
---|---|---|
| ||
<requires groupId="..." artifactId="..." [platformId="..."] version="..." range="..." type="..." [classifier="...] [modelVersion="..."]> |
...
<component .../> |
...
<license .../> |
...
<provides .../> |
...
<requires .../> |
...
<supports .../> |
...
</requires> |
The following are mandatory elements:
...
The supports element indicates an optional transitive dependency.
Code Block | ||
---|---|---|
| ||
<supports groupId="..." artifactId="..." |
...
[platformId="..."] |
...
[version="..."] range="..." type="..." |
...
[classifier="..."]/> |
The following are mandatory elements
...
The following is a pseudo-example of a Project Dependency Tree
...
Code Block | ||
---|---|---|
| ||
<project modelVersion="..." groupId="..." artifactId="..." [platformId="..."] version="..."> |
...
<generator name="Apache Maven" version="5.0.0" url="http://maven.apache.org"/> |
...
...
<information> |
...
<!-- container for descriptive information --> |
...
[<name>...</name>] |
...
[<description>...</description>] |
...
... |
...
...
</information> |
...
<license spdx="..."/> |
...
<license spdx="..."/> |
...
... |
...
<license spdx="..."/> |
...
...
<artifacts [platformId="..."]> |
...
<artifact type="..." [classifier="..."]> |
...
<information> <!-- optional element if need to override root level information for specific artifacts --> |
...
</information> |
...
<!-- |
...
components are internal packaging constructs used by the packaging type but requiring more general validation |
...
e.g. for Java 9+ the ids could be the module ids if we wanted to validate that the module ids were unique in the |
...
...
|
...
|
...
|
...
|
...
effective tree. |
...
--> |
...
<component id="..."/> |
...
<component id="..."/> |
...
... |
...
<component id="..."/> |
...
<!-- |
...
If the artifact has a different set of licenses from those defined at the project level, we define the licenses |
...
of this artifact here. Otherwise we defer to the licenses defined at the top level of the project. |
...
licensing is a top level concern, and legitimately can vary per artifact. Let's not solve license compatibility, |
...
rather leverage https://spdx.org/ |
...
--> |
...
<license spdx="..."/> |
...
<license spdx="..."/> |
...
... |
...
<license spdx="..."/> |
...
<!-- |
...
provides is a marker that we have duplication of content. This could be because we are much like the many servlet-api jar |
...
files where there are many GAV's of the same javax.servlet:servlet-api:3.0 thus we could have the case where |
...
org.jboss.spec.javax.servlet:jboss-servlet-api_3.0_spec:jar:1.0.2.Final PROVIDES javax.servlet:servlet-api:3.0 |
...
org.jboss.spec.javax.servlet:jboss-servlet-api_3.0_spec:jar:1.0.1.Final PROVIDES javax.servlet:servlet-api:3.0 |
...
org.jboss.spec.javax.servlet:jboss-servlet-api_3.0_spec:jar:1.0.0.Final PROVIDES javax.servlet:servlet-api:3.0 |
...
org.mortbay.jetty:servlet-api-3.0:jar:7.0.0pre2 PROVIDES javax.servlet:servlet-api:3.0 |
...
similarly org.slf4j:log4j-over-slf4j:jar:1.7.21 PROVIDES log4j:log4j:[1.0,2) |
...
The consumer of the tree can then decide if/when/how to collapse redundant nodes as they see fit. |
...
TODO: decide optionality of version and range attributes |
...
--> |
...
<provides groupId="..." artifactId="..." [platformId="..."] version="..." [range="..."] type="..." [classifier="..."]> |
...
<!-- no elements here as we have "rebundled" hence implicitly promoted up one level--> |
...
</provides> |
...
<provides groupId="..." artifactId="..." [platformId="..."] version="..." [range="..."] type="..." [classifier="..."]/> |
...
... |
...
<provides groupId="..." artifactId="..." [platformId="..."] version="..." [range="..."] type="..." [classifier="..."]/> |
...
<!-- |
...
requires are the mandatory dependencies. This is effectively a recursive artifact where the GAV is not inherited and |
...
where we have discarded the information section. If you want those details, fetch that project's dependencies trees. |
...
--> |
...
<requires groupId="..." artifactId="..." [platformId="..."] version="..." range="..." type="..." [classifier="..."]> |
...
<component id="..."/ |
...
> <license spdx:id="..."/> |
...
<provides groupId="..." artifactId="..." [platformId="..."] version="..." [range="..."] type="..." [classifier="..."]/> |
...
<requires groupId="..." artifactId="..." [platformId="..."] version="..." range="..." type="..." [classifier="..."]> |
...
... </requires> <supports groupId="..." artifactId="..." [platformId="..."] version="..." [range="..."] type="..." [classifier="..."]/> |
...
</requires> |
...
<requires groupId="..." artifactId="..." [platformId="..."] version="..." range="..." type="..." [classifier="..."]> |
...
... |
...
</requires> |
...
... |
...
<requires groupId="..." artifactId="..." [platformId="..."] version="..." range="..." type="..." [classifier="..."]> |
...
... |
...
</requires> |
...
<!-- |
...
supports are the optional dependencies. We list them here to aid in conflict resolution. We do not include a nested tree |
...
as a consumer would only pull them in if the consumer already has its own a requires for them, so we really only |
...
need to validate the range. |
...
TODO: decide optionality of range attribute |
...
TODO: decide if we want a version |
...
attribute --> |
...
<supports groupId="..." artifactId="..." [platformId="..."] version="..." [range="..."] type="..." [classifier="..."]/> |
...
<supports groupId="..." artifactId="..." [platformId="..."] version="..." [range="..."] type="..." [classifier="..."]/> |
...
<supports groupId="..." artifactId="..." [platformId="..."] version="..." [range="..."] type="..." [classifier="..."]/> |
...
</artifact> |
...
<artifact ...> |
...
... |
...
</artifact> |
...
... |
...
<artifact ...> |
...
... |
...
</artifact> |
...
...
</artifacts> |
...
<!-- if the project does not specify a platformId then we can include additional platform details that were part of the atomic deployment --> |
...
<artifacts platformId="..."> |
...
... |
...
</artifacts> |
...
... |
...
<artifacts platformId="..."> |
...
... |
...
</artifacts> |
...
</project> |
Constructing a Project Dependency Trees model
...
Here is a draft XML schema:
...
Code Block | ||
---|---|---|
| ||
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema" > |
...
<xsd:simpleType name=”coordinate”> |
...
<xsd:restriction base=”xsd:string”> |
...
<!-- TODO add pattern for groupId/artifactId/platformId/version/type/classifier valid values --> |
...
</xsd:restriction> |
...
</xsd:simpleType> |
...
<xs:element name="project"> |
...
<xs:annotation> |
...
<xs:documentation source="version">5.0.0+</xs:documentation> |
...
<xs:documentation source="description"> |
...
The <code><project></code> element is the root of the project |
...
dependency trees. |
...
</xs:documentation> |
...
</xs:annotation> |
...
<xs:complexType> |
...
<xs:attribute name="modelVersion" type="xs:string"/> |
...
<xs:attribute name="groupId" type="coordinate"/> |
...
<xs:attribute name="artifactId" type="coordinate"/> |
...
<xs:attribute name="version" type="coordinate"/> |
...
<xs:attribute name="platformId" type="coordinate" use="optional"/> |
...
<xs:all> |
...
<xs:element ref="generator" minOccurs="1" maxOccurs="1"/> |
...
<xs:element ref="information" minOccurs="0" maxOccurs="1"/> |
...
<xs:element ref="license" minOccurs="0" maxOccurs="unbounded"/> |
...
<xs:element ref="artifacts" minOccurs="1" maxOccurs="unbounded"/> |
...
</xs:all> |
...
</xs:complexType> |
...
</xs:element> |
...
<xs:element name="generator"> |
...
<xs:annotation> |
...
<xs:documentation source="version">5.0.0+</xs:documentation> |
...
<xs:documentation source="description"> |
...
The <code><generator></code> element identifies the build tool |
...
responsible for creating this document |
...
</xs:documentation> |
...
</xs:annotation> |
...
<xs:complexType> |
...
<xs:attribute name="name" type="xs:string"/> |
...
<xs:attribute name="version" type="xs:string"/> |
...
<xs:attribute name="url" type="xs:string"/> |
...
</xs:complexType> |
...
</xs:element> |
...
<xs:element name="information"> |
...
<xs:annotation> |
...
<xs:documentation source="version">5.0.0+</xs:documentation> |
...
<xs:documentation source="description"> |
...
The <code><information></code> element is a container for |
...
descriptive information about either all the artifacts in a project or |
...
a specific artifact. |
...
</xs:documentation> |
...
</xs:annotation> |
...
<xs:complexType> |
...
<xs:all> |
...
<xs:element name="name" type="xs:string" maxOccurs="1"/> |
...
<xs:element name="description" type="xs:string" maxOccurs="1"/> |
...
<!-- TODO add additional elements --> |
...
</xs:all> |
...
</xs:complexType> |
...
</xs:element> |
...
<xs:element name="license" xmlns:spdx="http://spdx.org/rdf/terms#"> |
...
<xs:annotation> |
...
<xs:documentation source="version">5.0.0+</xs:documentation> |
...
<xs:documentation source="description"> |
...
The <code><license></code> element defines one of the licenses |
...
under which the artifacts are made available. Where a license is |
...
attached to the <code><project></code> element this defines the |
...
default licenses for all artifacts in the project. Where a license is |
...
attached to an <code><artifact></code> element this signifies |
...
that the specific artifact is covered by the |
...
<code><license></code> elements defined within that |
...
<code><artifact></code> element. Licenses are identified using |
...
the <a href="http://spdx.org">SPDX</ |
...
a> identifiers |
...
</xs:documentation> |
...
</xs:annotation> |
...
<xs:complexType> |
...
<xs:attribute name="spdx" type="xs:string"/> |
...
</xs:complexType> |
...
</xs:element> |
...
<xs:element name="artifacts"> |
...
<xs:annotation> |
...
<xs:documentation source="version">5.0.0+</xs:documentation> |
...
<xs:documentation source="description"> |
...
The <code><artifacts></code> element is a container for |
...
details of artifacts. When the <code><artifacts></code> attribute |
...
is missing, then the artifacts listed are not platform specific. |
...
The <code><artifacts></code> must be unique with respect to their |
...
<code><platformId></code>, i.e. it cannot be repeated. |
...
If the <code><project></code> element has a |
...
<code><platformId></code> then there must be only one |
...
<code><artifacts></code> element and it must have the matching |
...
<code><platformId></code>. |
...
</xs:documentation> |
...
</xs:annotation> |
...
<xs:complexType> |
...
<xs:attribute name="platformId" type="coordinate" use="optional"/> |
...
<xs:sequence> |
...
<xs:element ref="artifact" minOccurs="1" maxOccurs="unbounded"/> |
...
</xs:sequence> |
...
</xs:complexType> |
...
</xs:element> |
...
<xs:element name="artifact"> |
...
<xs:annotation> |
...
<xs:documentation source="version">5.0.0+</xs:documentation> |
...
<xs:documentation source="description"> |
...
The <code><artifact></code> element represents an artifact |
...
associated with the project. |
...
</xs:documentation> |
...
</xs:annotation> |
...
<xs:complexType> |
...
<xs:attribute name="type" type="coordinate"/> |
...
<xs:attribute name="classifier" type="coordinate" use="optional"/> |
...
<xs:all> |
...
<xs:element ref="information" minOccurs="0" maxOccurs="1"/> |
...
<xs:element ref="license" minOccurs="0" maxOccurs="unbounded"/> |
...
<xs:element ref="component" minOccurs="0" maxOccurs="unbounded"/> |
...
<xs:element ref="provides" minOccurs="0" maxOccurs="unbounded"/> |
...
<xs:element ref="requires" minOccurs="0" maxOccurs="unbounded"/> |
...
<xs:element ref="supports" minOccurs="0" maxOccurs="unbounded"/> |
...
</xs:all> |
...
</xs:complexType> |
...
</xs:element> |
...
<xs:element name="component"> |
...
<xs:annotation> |
...
<xs:documentation source="version">5.0.0+</xs:documentation> |
...
<xs:documentation source="description"> |
...
The <code><component></code> element represents a type specific |
...
component that is present within the artifact. For example a "jar" |
...
artifact might list the Java 9+ modules that are included within |
...
the "jar". Other file types can use the component according to the |
...
conventions of that file type. The component information is intended |
...
to assist build time tools in conflict detection when resolving |
...
the composite dependency tree according to the build tools |
...
dependency resolution strategy. |
...
</xs:documentation> |
...
</xs:annotation> |
...
<xs:complexType> |
...
<xs:attribute name="id" type="xs:string"/> |
...
</xs:complexType> |
...
</xs:element> |
...
<xs:element name="provides"> |
...
<xs:annotation> |
...
<xs:documentation source="version">5.0.0+</xs:documentation> |
...
<xs:documentation source="description"> |
...
The <code><provides></code> element represents a semantic |
...
equivalence with another artifact. There are several ways the element |
...
can be used. |
...
<nl> |
...
<li> |
...
When an artifact directly includes the same content as another |
...
project's artifacts, for example there are some "jar" files that |
...
will embed other artifacts to produce a so-called "uber-jar". |
...
</li> |
...
<li> |
...
When an artifact re-implements the API of another project's |
...
artifact. For example: log4j-over-slf4j reimplements the log4j |
...
API. |
...
</li> |
...
<li> |
...
When a set of projects are co-operating to provide multiple |
...
implementations of a "virtual" project artifact. For example: |
...
slf4j-log4j, slf4j-jul, and logback could all be considered |
...
as providing a slf4j-impl virtual project artifact. There would |
...
be no actual project at the slf4j-impl coordinates, but |
...
slf4j-api could declare a requirement on the "virtual" project |
...
artifact in order to ensure that an implementation is available |
...
to consumers of the API |
...
</li> |
...
</nl> |
...
</xs:documentation> |
...
</xs:annotation> |
...
<xs:complexType> |
...
<xs:attribute name="groupId" type="coordinate"/> |
...
<xs:attribute name="artifactId" type="coordinate"/> |
...
<xs:attribute name="platformId" type="coordinate" use="optional"/> |
...
<xs:attribute name="version" type="coordinate"/> |
...
<xs:attribute name="range" type="xs:string"/> |
...
<xs:attribute name="type" type="coordinate"/> |
...
<xs:attribute name="classifier" type="coordinate" use="optional"/> |
...
</xs:complexType> |
...
</xs:element> |
...
<xs:element name="requires"> |
...
<xs:annotation> |
...
<xs:documentation source="version">5.0.0+</xs:documentation> |
...
<xs:documentation source="description"> |
...
The <code><requires></code> element represents a hard dependency |
...
on another project's artifact. If the <code><version></code> |
...
attribute is missing then this indicates that the dependency is |
...
a virtual dependency, and there must be no child elements. |
...
The <code><modelVersion></code> attribute must only be present |
...
if the dependent project's <code><modelVersion></code> is newer |
...
than the <code><modelVersion></code> specified on the root |
...
<code><project></code> element. The presence of this element |
...
indicates that the child information was the result of an XSLT |
...
transformation of a newer <code><modelVersion></code> and |
...
indicates that a build tool understanding the newer |
...
<code><modelVersion></code> may want to fetch the dependencies |
...
tree and process it directly in order to obtain the most correct |
...
model of the dependency. |
...
</xs:documentation> |
...
</xs:annotation> |
...
<xs:complexType> |
...
<xs:attribute name="groupId" type="coordinate"/> |
...
<xs:attribute name="artifactId" type="coordinate"/> |
...
<xs:attribute name="platformId" type="coordinate" use="optional"/> |
...
<xs:attribute name="version" type="coordinate" use="optional"/> |
...
<xs:attribute name="range" type="xs:string"/> |
...
<xs:attribute name="type" type="coordinate"/> |
...
<xs:attribute name="classifier" type="coordinate" use="optional"/> |
...
<xs:attribute name="modelVersion" type="xs:string" use="optional"/> |
...
<xs:all> |
...
<xs:element ref="license" minOccurs="0" maxOccurs="unbounded"/> |
...
<xs:element ref="component" minOccurs="0" maxOccurs="unbounded"/> |
...
<xs:element ref="provides" minOccurs="0" maxOccurs="unbounded"/> |
...
<xs:element ref="requires" minOccurs="0" maxOccurs="unbounded"/> |
...
<xs:element ref="supports" minOccurs="0" maxOccurs="unbounded"/> |
...
</xs:all> |
...
</xs:complexType> |
...
</xs:element> |
...
<xs:element name="supports"> |
...
<xs:annotation> |
...
<xs:documentation source="version">5.0.0+</xs:documentation> |
...
<xs:documentation source="description"> |
...
The <code><supports></code> element represents a soft dependency |
...
on another project's artifact. This element is provided in order to |
...
allow build time tools to perform conflict resolution when determining |
...
the effective tree from multiple dependencies. |
...
</xs:documentation> |
...
</xs:annotation> |
...
<xs:complexType> |
...
<xs:attribute name="groupId" type="coordinate"/> |
...
<xs:attribute name="artifactId" type="coordinate"/> |
...
<xs:attribute name="platformId" type="coordinate" use="optional"/> |
...
<xs:attribute name="version" type="coordinate"/> |
...
<xs:attribute name="range" type="xs:string"/> |
...
<xs:attribute name="type" type="coordinate"/> |
...
<xs:attribute name="classifier" type="coordinate" use="optional"/> |
...
</xs:complexType> |
...
</xs:element> |
...
</xs:schema> |