You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maven.apache.org by hb...@apache.org on 2022/02/03 07:09:49 UTC

[maven-site] 06/07: WIP

This is an automated email from the ASF dual-hosted git repository.

hboutemy pushed a commit to branch maven-repository-layout
in repository https://gitbox.apache.org/repos/asf/maven-site.git

commit d345620d9fc188a420d54b567325fa3af829e4d8
Author: Tamas Cservenak <ta...@cservenak.net>
AuthorDate: Fri Jan 21 09:52:08 2022 +0100

    WIP
---
 content/markdown/repositories/artifacts.md | 122 +++++++++++++++++++++++++++++
 content/markdown/repositories/index.md     |  75 +++---------------
 content/markdown/repositories/layout.md    |  56 ++++++++++---
 content/site.xml                           |   1 +
 4 files changed, 182 insertions(+), 72 deletions(-)

diff --git a/content/markdown/repositories/artifacts.md b/content/markdown/repositories/artifacts.md
new file mode 100644
index 0000000..d2221ba
--- /dev/null
+++ b/content/markdown/repositories/artifacts.md
@@ -0,0 +1,122 @@
+# Maven Artifacts
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+Artifact is "anything" that Maven downloads, installs or deploys for you. Most of them are POMs and JARs but 
+the artifact can be really anything. A very important thing about artifacts is that they have coordinates,
+so they are not "just files", but they are files that are in some way addressable by Maven.
+
+Artifact coordinates, are most often represented as `groupId:artifactId:version`, or GAV in short or when 
+informally used (please note that Artifact coordinates has more fields, but for brevity we still call the 
+coordinates "GAV", not "GAVCE"). The artifact coordinate uniquely describe the artifact you are referring to, 
+but does not tell anything about its source (or origin). It is up to Maven to figure out (or you to tell Maven 
+how to figure it out).
+
+While Maven internally uses notion of "artifact" thoroughly (just look at sources!), end user may never hit this name.
+That's due the fact, that while for Maven, "everything is artifact" (internally), Maven end users actually speak about
+"projects", "parent projects", "dependencies", "build plugins", "build extensions" and so on.
+
+## Artifact properties
+
+The artifacts that Maven (internally) uses has following (for our topic related) properties:
+
+| Name       | Description                                       |
+|------------|---------------------------------------------------|
+| groupId    | The artifact group                                |
+| artifactId | The artifact name                                 |
+| version    | The artifact version                              |
+| classifier | The artifact distinguishing classifier (optional) |
+| extension  | The artifact extension                            |
+
+Some more properties worth mention, is a bit of special one: `baseVersion` that is actually derived from version 
+(or other way around, depends on context): for release artifacts holds same value as `version`, for snapshot artifacts 
+holds "non-timestamped snapshot version". For example, for snapshot `version` "1.0-20220119.164608-1" value of the 
+`baseVersion` would have value "1.0-SNAPSHOT". So, `version` and `baseVersion` are linked, derived from each other, 
+but they have different values only in case of snapshots.
+
+## But where do I set Artifact extension?
+
+In short, nowhere. Or maybe "you rarely have to". Maven POM (where you declare your project, parent project,
+dependencies, plugins and other), maps those elements onto artifact coordinates with some extra logic. In case
+of "project" and "parent project" aka POMs:
+
+| Project    | Artifact      |
+|------------|---------------|
+| groupId    | -> groupId    |
+| artifactId | -> artifactId |
+| version    | -> version    |
+| classifier | ->            |
+| extension  | -> `pom`      |
+
+In case of "build plugins" and "build extensions", as they are JARs, this is how corresponding elements are mapped:
+
+| Plugin     | Artifact      |
+|------------|---------------|
+| groupId    | -> groupId    |
+| artifactId | -> artifactId |
+| version    | -> version    |
+| classifier | ->            |
+| extension  | -> `jar`      |
+
+And finally, in case of "dependencies", this is the mapping (no, scope is NOT part of artifact coordinates, is used in
+dependency resolution only):
+
+| Dependency | Artifact                                  |
+|------------|-------------------------------------------|
+| groupId    | -> groupId                                |
+| artifactId | -> artifactId                             |
+| version    | -> version                                |
+| classifier | -> classifier                             |
+| type       | -> type handler provided, or same as type |
+
+Here, we need to make a short detour to explain "type" (of a dependency) and how it becomes artifact extension.
+
+Maven for dependencies defines "type", that describes what that dependency is (should it be added to classpath and
+many other things). Plugins and extensions may define new types, that is usually a must for plugins introducing
+a "packaging" (lifecycle mapping) by providing ArtifactHandlers components with name corresponding to type name.
+
+Maven Core out of the box defines following "types" (ArtifactHandlers):
+
+| Name         | Extension | Classifier   |
+|--------------|-----------|--------------|
+| pom          | `pom`     |              |
+| jar          | `jar`     |              |
+| maven-plugin | `jar`     |              |
+| ear          | `ear`     |              |
+| ejb          | `jar`     |              |
+| ejb-client   | `jar`     | `ejb-client` |
+| javadoc      | `jar`     | `javadoc`    |
+| java-source  | `jar`     | `sources`    |
+| rar          | `rar`     |              |
+| test-jar     | `jar`     | `tests`      |
+| war          | `war`     |              |
+| **any**      | any       |              |
+
+So, from table above, we can see that if we define dependency type as "war", we will hit the "war" handler, that will
+result in the `war` extension (may not be obvious, as type and extension we end up is same, but internally this 
+indirection does happen). More obvious is type "test-jar", where we end up with extension `jar`. Finally, the **any** 
+last row will be used if none above matches, hence in that case your "type" is used just as "extension", for example 
+you can write `<type>tar.gz</type>` for dependency, and you will end up with extension `tar.gz` (all this happens 
+because as there is no artifact handler named "tar.gz" in table above). Still, you should be aware that this table 
+above may be extended by various plugins and extensions you use in your build!
+
+In short, this is how various Maven bits like "project", "parent project", "plugin", "extension" and "dependency"
+have artifact coordinates mapped from POM elements. Using this knowledge, we can always deduce the artifact coordinate 
+of these POM elements.
diff --git a/content/markdown/repositories/index.md b/content/markdown/repositories/index.md
index 848be72..807368e 100644
--- a/content/markdown/repositories/index.md
+++ b/content/markdown/repositories/index.md
@@ -20,69 +20,18 @@ under the License.
 -->
 
 Apache Maven uses repositories to store artifacts. Your dependencies are being downloaded from repositories,
-and your artifacts are being stored (installed, uploaded) into repositories as well. This is one of the 
+and artifacts you build are being stored (installed, uploaded) into repositories as well. This is one of the 
 fundamental concepts of Maven since its inception: Maven command line tool and Maven Repositories were mold together
 and developed since the beginning of Maven project itself.
 
-As you may know, Maven addresses artifacts using coordinates, that are most often represented as 
-`groupId:artifactId:version`, or GAV in short or when informally used (please note that Artifact coordinates has 
-more fields, but for brevity we still call the coordinates "GAV", not "GAVCE"). The artifact coordinate uniquely 
-describe the artifact you are referring to, but does not tell anything about its source (or origin). It is up to 
-Maven to figure out (or you to tell Maven how to figure it out).
-
-While Maven internally uses notion of "artifact" thoroughly (just look at sources!), end user may never hit this name.
-That's due the fact, that while for Maven, "everything is artifact" (internally), the end users actually speak about
-"projects", "parent projects", "dependencies", "build plugins", "build extensions" and so on.
-
-## Artifact properties
-
-The artifacts that Maven (internally) uses has following (among many others, but for our topic related) properties:
-
-| Name       | Description |
-|------------|-------------|
-| groupId    | The artifact group name |
-| artifactId | The artifact name |
-| version    | The artifact version |
-| classifier | The artifact distinguishing classifier |
-| extension  | The artifact extension |
-
-And some more, a bit of special one: `baseVersion` that is actually derived from version (or other way around, 
-depends on context): for release artifacts holds same value as `version`, for snapshot artifacts holds "non-timestamped 
-snapshot version". For example, for `version` "1.0-20220119.164608-1" value the `baseVersion` would have value 
-"1.0-SNAPSHOT".
-
-## But where do I set artifact extension?
-
-In short, nowhere. Or maybe "you rarely have to". Maven POM (where you declare your project, parent project,
-dependencies, plugins and other), maps those elements onto artifact coordinates with some simple mapping. In case
-of "project" and "parent project" (aka POMs):
-
-| Project    | Artifact      |
-|------------|---------------|
-| groupId    | -> groupId    |
-| artifactId | -> artifactId |
-| version    | -> version    |
-| classifier | -> empty      |
-| extension  | -> "pom"      |
-
-In case of "build plugins" and "build extensions", as they are JARs, this is how corresponding elements are mapped:
-
-| Plugin     | Artifact      |
-|------------|---------------|
-| groupId    | -> groupId    |
-| artifactId | -> artifactId |
-| version    | -> version    |
-| classifier | -> empty      |
-| extension  | -> "jar"      |
-
-And finally, in case of "dependencies", this is the mapping:
-
-| Dependency | Artifact                                  |
-|------------|-------------------------------------------|
-| groupId    | -> groupId                                |
-| artifactId | -> artifactId                             |
-| version    | -> version                                |
-| classifier | -> classifier                             |
-| type       | -> type handler provided, or same as type |
-
-Here, we need to make a short turn to explain "type" (of a dependency) and how it becomes artifact extension.
+As you may know, Maven addresses artifacts using coordinates. The artifact coordinate uniquely describe the artifact 
+you are referring to, but does not tell anything about its source (or origin). This is where
+Maven Repositories come into picture, that holds the artifacts laid out (published) according to Maven Repository
+Layout. And this is where the circle closes: artifacts, being laid out in defined layout, consumed and published
+by Maven.
+
+Sections:
+* [Artifacts](artifacts.md)
+* [Layout](layout.md)
+* [Local Repositories](local.md)
+* [Remote Repositories](remote.md)
diff --git a/content/markdown/repositories/layout.md b/content/markdown/repositories/layout.md
index 98ba670..19dae2f 100644
--- a/content/markdown/repositories/layout.md
+++ b/content/markdown/repositories/layout.md
@@ -21,8 +21,8 @@ under the License.
 
 The layout is responsible to translate the artifact coordinates into generic paths, that is later used to construct some
 URI (file path, URL, it depends on context). Obviously, since Maven;s inception in 2002 the layout evolved as well.
-Due simplicity, we will cover current layout (aka "maven2" or "default"), as since Maven 3.x release, the deprecated
-"Maven1 layout" is not supported anymore.
+For simplicity, we will cover current layout (aka "maven2", "default"), as since Maven 3.x release, the deprecated
+"Maven1 layout" (aka "legacy") is not supported anymore.
 
 This above implies following: if the repository contains a file that is "not on layout" (does not obey layout 
 transformation rules discussed below), that file is "not addressable" by Maven coordinates, you cannot make Maven
@@ -31,20 +31,20 @@ to download it using GAV coordinates!
 The original premise of layout was simplicity: from historical perspective, a remote repository was expected to be run
 by some computer with file storage (where artifacts were laid down) and served by a HTTP server, essentially publishing 
 the files on file paths for consumption (mainly for HTTP GET requests). Actually, the reason of layout change between
-Maven1 and Maven2 (the today's "default") was exactly that: Maven1 layout was stressing the underlying file system 
-way too much, it was not scaling in this setup.
+Maven1 and current Maven was exactly that: Maven1 layout was stressing the underlying file system way too much, it 
+was not scaling in this setup.
 
 The transformation rule is quite simple for that matter: consider artifact properties below:
 
 | Name       | Transformation                                          | Result example                           |
 |------------|---------------------------------------------------------|------------------------------------------|
 | groupId    | Replace "." (dot) characters with "/" (slash) character | `org.apache.maven` -> `org/apache/maven` |
-| artifactId | none | `apache-maven` -> `apache-maven`         |
-| version    | none | `3.8.4` -> `3.8.4`                       |
-| classifier | none | `bin` -> `bin`                           |
-| extension  | none | `tar.gz` -> `tar.gz`                     |
+| artifactId | none                                                    | `apache-maven` -> `apache-maven`         |
+| version    | none                                                    | `3.8.4` -> `3.8.4`                       |
+| classifier | none                                                    | `bin` -> `bin`                           |
+| extension  | none                                                    | `tar.gz` -> `tar.gz`                     |
 
-And using these properties transformed as above we can construct following layout (if classifier not present):
+And using these properties transformed as above we can construct following path (if classifier not present):
 
 ```
 ${groupId}/${artifactId}/${version}/${artifactId}-${version}.${extension}
@@ -67,3 +67,41 @@ is translated to path:
 ```
 org/apache/maven/apache-maven/3.8.4/apache-maven-3.8.4-bin.tar.gz
 ```
+
+And that is it! By applying this "algorithm" above to ANY Artifact we can, we can build up the path segment that
+artifact is expected to be.
+
+# A word about Maven1 layout
+
+Maven1 aka "legacy" layout **is unsupported since Maven 3.x** (Maven 2.x supported it to ease transition from 1.x to 
+2.x), but is still worth a few words.
+
+The Maven1 layout was not applying groupId transformation (hence the path, if it had dots, still contained it), and
+used "type" in plural as second level directory. This is the reason why it caused FS stress, as these directories
+ended up containing a LOT of files (in case of many versions existed).
+
+| Name       | Transformation                        | Result example                           |
+|------------|---------------------------------------|------------------------------------------|
+| groupId    | none                                  | `org.apache.maven` -> `org.apache.maven` |
+| artifactId | none                                  | `apache-maven` -> `apache-maven`         |
+| version    | none                                  | `3.8.4` -> `3.8.4`                       |
+| extension  | none                                  | `pom` -> `pom`                           |
+| type       | derived by extension by appending 's' | `pom` -> `poms`                          |
+
+And using these properties transformed as above we can construct following path:
+
+```
+${groupId}/${type}/${artifactId}-${version}.${extension}
+```
+
+So the example artifact above:
+
+```
+org.apache.maven:apache-maven:3.8.4:pom
+```
+
+is translated to path:
+
+```
+org.apache.maven/poms/apache-maven-3.8.4.pom
+```
diff --git a/content/site.xml b/content/site.xml
index eaca2a2..c66fc03 100644
--- a/content/site.xml
+++ b/content/site.xml
@@ -75,6 +75,7 @@ under the License.
       <item name="Maven Plugins" href="/plugins/index.html" />
       <item name="Maven Extensions" href="/extensions/index.html" />
       <item name="Maven Repositories" href="/repositories/index.html">
+        <item name="Maven Artifacts" href="/repositories/artifacts.html" />
         <item name="Maven Layout" href="/repositories/layout.html" />
         <item name="Maven Local Repository" href="/repositories/local.html" />
         <item name="Maven Remote Repositories" href="/repositories/remote.html" />