This is an automated email from the ASF dual-hosted git repository. elharo pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/maven-site.git
The following commit(s) were added to refs/heads/master by this push: new 228c8777 Add dependencies page (#662) 228c8777 is described below commit 228c8777222e0d6f1d029dc8b0e81f6721217c81 Author: Elliotte Rusty Harold <elh...@users.noreply.github.com> AuthorDate: Tue Mar 4 12:49:45 2025 +0000 Add dependencies page (#662) * Add dependencies page --- content/markdown/repositories/dependencies.md | 232 ++++++++++++++++++++++++++ content/markdown/repositories/index.md | 20 ++- 2 files changed, 243 insertions(+), 9 deletions(-) diff --git a/content/markdown/repositories/dependencies.md b/content/markdown/repositories/dependencies.md new file mode 100644 index 00000000..262a41bd --- /dev/null +++ b/content/markdown/repositories/dependencies.md @@ -0,0 +1,232 @@ +# Maven Dependencies + +<!-- +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. +--> + +A dependency is a connection between a Maven project and an artifact. +Maven will add the artifact to one or more of the project's classpaths +or otherwise use it when building the project. +A dependency includes the artifact coordinates (group ID, artifact ID, and version) +and metadata about how the artifact is used by the project. This metadata includes +the scope in which the artifact is +added to the classpath and whether the artifact is required or optional. +Different projects can have dependencies on the same artifact with different scopes +and optionality. That is, a dependency is a property of a project, not an artifact. + +A dependency is defined by a `dependency` element in the project's +pom.xml file. The child elements of the `dependency` specify the +coordinates of the artifact to depend on and the scope in which that +dependency applies. Consider this `dependency` element: + +```xml +<dependency> + <groupId>com.google.guava</groupId> + <artifactId>guava</artifactId> + <version>33.4.0-jre</version> + <scope>test</scope> +</dependency> +``` + +This element says that the artifact com.google.guava:guava:33.4.0-jre +should be loaded from the Maven repository system and added to the +classpath used to run tests. + +Occasionally, the group ID, artifact ID, and version are not enough to +uniquely identify an artifact. Sometimes you also need an extension +and/or a classifier. Classifiers are added directly to the `dependency` +element as in this dependency on the +io.netty:netty-transport-native-epoll native library for Linux on the 64-bit +X86 architecture: + +```xml +<dependency> + <groupId>io.netty</groupId> + <artifactId>netty-transport-native-epoll</artifactId> + <version>4.1.192</version> + <classifier>linux-x86_64</classifier> +</dependency> +``` + +Extensions are a little more complicated. The `dependency` element does +not have an `extension` child element. Instead it has a `type` element +which maps to an extension and sometimes a classifier. For example, here +is a dependency with type test-jar: + +```xml +<dependency> + <groupId>org.example</groupId> + <artifactId>reusable-test-support</artifactId> + <version>2.3</version> + <type>test-jar</type> +</dependency> +``` + +This element says that the artifact +org.example:reusable-test-support:2.3::jar should be loaded from the +Maven repository systems. Although the type is `test-jar`, the extension +is `jar`. Dependency types do not one-to-one match artifact extensions. + +The `classifier`, `type`, `optional`, and `scope` elements all have defaults and are often +omitted. The default classifier is the empty string. The default type is +jar. The default opitonality is false. The default scope is compile. +Thus this dependency element adds the artifact nu.xom:xom:1.3.9::jar to all of the +project's classpaths as a required dependency: + +```xml +<dependency> + <groupId>nu.xom</groupId> + <artifactId>xom</artifactId> + <version>1.3.9</version> +</dependency> +``` + +A dependency element does not say in which repository to look for the corresponding artifact. +That is determined by the settings.xml file and the `repositories` element in the +pom.xml file and its ancestors. + +## Dependency Scopes + +Every dependency has a scope that determines which classpaths the +artifact referenced by the dependency is added to. For example, +should it be added to compile-time classpath, the test classpath, or +both? The default scope when none is explicitly specified is `compile`. + +Different projects may assign different scopes to the same artifact. For +instance, one project might use com.google.guava:34.4.0-jre only for +tests and thus set the scope to `test`. Another might need it at runtime +but not when the project is compiled, and thus set the scope to +`runtime`. A third project might need it for compiling, running, and +testing and thus set the scope to `compile`. + +The scope does not have any effect on which artifact is loaded. Instead it determines: + +1. Where the artifact is loaded from +2. Which classpaths the artifact is added to +3. Whether the artifact's own dependencies are also added to this project's classpath + +Maven has six dependency scopes: + +* compile - Compile scope artifacts are available in all classpaths. This is the default if no scope is provided. +* provided - Maven expects the JDK or a container to provide the artifact at runtime. It does not add it to the classpath. +* runtime - The artifact is required for execution but not for compilation. It is in the runtime and test classpaths, but not the compile classpath. +* test - The artifact is needed for tests but not by non-test code. +* system - The artifact is loaded from the local file system. The path to the file is specified by the `systempath` child of the `dependency` element. +* import - Replace this dependency with the dependencies in the specified POM's `dependencyManagement` element. Only used when the type is pom. + +<!-- As I write this, I'm realizing that Maven overloads dependency scope +for multiple different purposes. In particular we've confused the scope in the +classpath with where the artifact lives and how it's found. +Scope should be one of compile, runtime, test, or all. +system should be replaced by systempath. provided and import should be separate elements. +Or perhaps we should have a separate source element that has values +repository, system (or url), provided, and import. +Not that we're going to fix any of this now, but it is worth +understanding why this is confusing. +--> + +Maven does not have a compileOnly scope that is available at compile time +but not at runtime. Compile scope dependencies are available in all classpaths. + +## Dependency Types + +Every dependency has a type that indicates the extension and the classifier +for the artifact, though the type-specified classifier can be overridden by +an explicit `classifier` element. +The type is set by the `type` element. +The default type when no `type` element is present is `jar`. +Different projects may assign different types to the same artifact. + +This dependency element retrieves com.google.guava:guava:31.0.0::pom. + +```xml +<dependency> + <groupId>com.google.guava</groupId> + <artifactId>guava</artifactId> + <version>31.0.0</version> + <type>pom</type> +</dependency> +``` + +Here the type of the dependency and the extension of the artifact are the same, +but that is not always the case. +For instance, the test-jar type selects an artifact with the extension `jar`. + +Out of the box, Maven defines 11 dependency types: + +| Type Name | Extension | Classifier | +|--------------|-----------|--------------| +| jar | `jar` | | +| pom | `pom` | | +| 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` | | + +From the table above, you can see that if the dependency type is "war", Maven retrieves +an artifact with the `war` extension. If the dependency type is "test-jar", Maven retrieves +an artifact with the `jar` extension and the classifier `tests`. + +Finally, if Maven does not recognize a type, then the type becomes the extension and the +classifier is empty. For example. +if the dependency type is `<type>tar.gz</type>`, the extension will also be `tar.gz`. +These mappings may be extended by plugins and extensions used in the build. + +Consider the artifact +`org.project:reusable-test-support:1.0:tests:jar`. With the type handlers above, +maybe surprisingly, a dependency on this very same artifact can be described in two ways: + +```xml +<dependency> + <groupId>org.project</groupId> + <artifactId>reusable-test-support</artifactId> + <version>1.0</version> + <classifier>tests</classifier> +</dependency> +``` + +and a completely equivalent dependency is: + +```xml +<dependency> + <groupId>org.project</groupId> + <artifactId>reusable-test-support</artifactId> + <version>1.0</version> + <type>test-jar</type> +</dependency> +``` + +The obvious difference is the presence of `classifier` in the first case, +and the absence of it in the second. However, in the second case, the `type` "test-jar" +implies a classifier of "tests". In both cases, the extension is "jar". +The first uses the default value for this property, while the second infers it from the type. + +The first way is more explicit and therefore preferred. In this case the type "test-jar" +serves as an alias for ordinary JARs with the "tests" classifier. If the +type handler carries important extra information such as custom packaging, using `type` +is more appropriate. + +Plugins and extensions can define new dependency types. This is usually required for +plugins that introduce a "packaging" (lifecycle mapping) by providing an `ArtifactHandler` +component with a name corresponding to the type name. + diff --git a/content/markdown/repositories/index.md b/content/markdown/repositories/index.md index b3a1de22..ffa8cb65 100644 --- a/content/markdown/repositories/index.md +++ b/content/markdown/repositories/index.md @@ -19,10 +19,10 @@ specific language governing permissions and limitations under the License. --> -Apache Maven uses repositories to store artifacts. Your dependencies are being downloaded from repositories, -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. +Apache Maven uses repositories to store artifacts. Your dependencies are downloaded from repositories, +and artifacts you build are 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 molded together and developed since the beginning of Maven project itself. <p align="center"> <img src="../repository/maven-repositories.png" border="0" usemap="#map" /> @@ -41,14 +41,16 @@ and developed since the beginning of Maven project itself. See also the [Introduction to Repositories](/guides/introduction/introduction-to-repositories.html) and [Repository Layout](../repository/layout.html). -As you may know, Maven addresses artifacts using artifact coordinates. The artifact coordinates 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. +Maven addresses artifacts using artifact coordinates. The artifact coordinates uniquely +identify an artifact, but do not say anything about its source or origin. This is where +Maven Repositories come into the picture. A repository holds the artifacts in a file +system or URL hierarchy laid out according to the Maven Repository +Layout. And this is where the circle closes: artifacts, being laid out in defined layout, +are consumed and published by Maven. Sections: * [Artifacts](artifacts.md) +* [Dependencies](dependencies.md) * [Metadata](metadata.md) * [Layout](layout.md) * [Local Repositories](local.md)