Apache Maven

Apache Maven

Maven Introduction

Apache Maven is a software project management and comprehension tool. Based on the concept of a project object model (POM), Maven can manage a project’s build, reporting and documentation from a central piece of information.

Maven’s main functions

  • manage project dependencies
  • build project artifacts

Maven’s Mechanism

Dependency

Dependency Management

Dependency management is one of Maven’s most powerful features. It allows developers to declare the libraries their project depends on, and Maven will automatically download these libraries and their dependencies from remote repositories.

In a Maven project, dependencies are declared in the pom.xml file. Together, the combination of groupId, artifactId, and version forms a unique coordinate that Maven uses to locate, download, and manage dependencies. This coordinate system is critical for resolving dependencies during the build process and ensuring that the correct versions of libraries are used in the project.

  • groupId: represents the organization or company that produces the project. It typically follows a reverse domain name convention to ensure uniqueness across the entire Maven ecosystem.
  • artifactId: identifies the specific project or module within the scope of the groupId. It is akin to the project’s name and should be unique within the groupId.
  • version: indicates the release version of the artifact. It follows semantic versioning rules and is crucial for dependency management.
1
2
3
4
5
6
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>

POM

POM (Project Object Model) is the core configuration file used by Maven to manage a project. It is an XML file that contains information about the project, its dependencies, and other settings.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<!-- Project Information -->
<!-- Define the coordinates of the project. -->
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>my-app</artifactId>
<version>1.0-SNAPSHOT</version>
<!-- Specifies the type of the package to be built (e.g., jar, war, ear). -->
<packaging>jar</packaging>

<!-- Project Description -->
<!-- Provide human-readable information about the project. -->
<name>My Java Application</name>
<description>This is a simple Java application using Maven.</description>
<url>http://example.com/my-app</url>

<!-- Repositories -->
<!-- Defines repositories where Maven looks for dependencies. -->
<repositories>
<repository>
<id>central</id>
<url>https://repo.maven.apache.org/maven2</url>
</repository>
</repositories>

<!-- ⭐Dependencies -->
<!-- <dependencies>: Lists the project's direct dependencies. -->
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.15</version>
</dependency>
</dependencies>

<!-- Build Settings -->
<!-- <build>: Contains configuration for the build process. -->
<!-- <plugins>: Configures Maven plugins that extend Maven's functionality, such as compiling the code or creating a JAR file. -->
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.2.2</version>
<configuration>
<archive>
<manifest>
<mainClass>com.example.App</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
</build>
</project>

Maven enforces a standardized directory layout for several key reasons, which contribute significantly to the efficiency, maintainability, and consistency of projects managed by Maven.

Convention Over Configuration
Configuration Over Code

Project Structure

JAR(Java ARchive) project structure

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
.
├── pom.xml # Maven project configuration file
├── src
│ ├── main
│ │ ├── java # Java source code
│ │ │ └── com.example # Package structure for classes
│ │ ├── resources # Resource files (like properties, XML)
│ │ │ └── config.properties # Example resource file
│ └── test # Test source code and resources
│ ├── java # Test Java source code
│ │ └── com.example # Package structure for test classes
│ └── resources # Test resources
└── target # Built output goes here
├── classes # Compiled .class files
└── my-library.jar # Final JAR file after build

WAR(Web ARchive) project structure

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
.
├── pom.xml # Maven project configuration file
├── src
│ ├── main
│ │ ├── java # Java source code
│ │ │ └── com.example # Package structure for classes
│ │ ├── resources # Resource files (like properties, XML)
│ │ └── webapp # Web application content
│ │ ├── WEB-INF # Web application metadata and private files
│ │ │ ├── classes # Compiled .class files
│ │ │ ├── lib # JAR files (dependencies)
│ │ │ └── web.xml # Deployment descriptor
│ │ ├── index.jsp # Main entry point for the web app
│ │ ├── static # Static resources (CSS, JavaScript, images)
│ │ │ ├── css
│ │ │ ├── js
│ │ │ └── img
│ │ └── META-INF # Metadata information
│ └── test # Test source code and resources
└── target # Built output goes here, including the .war file
└── classes # Compiled test classes

Dependency Scope

Maven uses dependency scopes to control how dependencies are included during different stages of the build process. The most common scopes include:

  • compile
    This is the default scope, used if none is specified. Compile dependencies are available in all classpaths of a project. Furthermore, those dependencies are propagated to dependent projects.
  • provided
    This is much like compile, but indicates you expect the JDK or a container to provide the dependency at runtime. For example, when building a web application for the Java Enterprise Edition, you would set the dependency on the Servlet API and related Java EE APIs to scope provided because the web container provides those classes. This scope is only available on the compilation and test classpath, and is not transitive.
  • runtime
    This scope indicates that the dependency is not required for compilation, but is for execution. It is in the runtime and test classpaths, but not the compile classpath.
  • test
    This scope indicates that the dependency is not required for normal use of the application, and is only available for the test compilation and execution phases. This scope is not transitive.
  • system
    This scope is similar to provided except that you have to provide the JAR which contains it explicitly. The artifact is always available and is not looked up in a repository.
  • import (only available in Maven 2.0.9 or later)
    This scope is only supported on a dependency of type pom in the section. It indicates the dependency to be replaced with the effective list of dependencies in the specified POM’s section. Since they are replaced, dependencies with a scope of import do not actually participate in limiting the transitivity of a dependency.
scope valid range transitive example
compile all spring-core
provided compile, test servlet-api
runtime runtime, test JDBC
test test JUnit
system compile, test

Transitive Dependency

A transitive dependency occurs when a project directly depends on another project, which in turn depends on a third project. Maven manages these transitive dependencies automatically, ensuring that all required libraries are available during the build process.

Exclude Dependencies

Maven allows you to exclude dependencies from a project by adding them to the <exclusions> tag in the <dependency> tag. This can be useful when you want to use a different version of a dependency than the one specified in the parent project.

Maven Lifecycle

The Maven lifecycle is a series of phases that define the order in which tasks are executed. The most commonly used lifecycle is the default lifecycle, which includes the following phases:

  • validate Validates that the project is correct and all necessary information is available.
  • compile Compiles the source code of the project.
  • test Runs tests for the project.
  • package Takes the compiled code and packages it in its distributable format, such as a JAR.
  • integrationtest: Processes and deploys the package if necessary into an environment where integration tests can be run.
  • verify Runs any checks to verify the package is valid and meets quality criteria.
  • install Installs the package into the local repository, for use as a dependency in other projects locally.
  • deploy Copies the final package to the remote repository for sharing with other developers and projects.
Author

Efterklang

Posted on

2024-07-18

Updated on

2024-09-18

Licensed under

Comments