Problem Statement
Explain Maven project structure, lifecycle, dependency management, and plugins. Include pom.xml configuration, repository management, and CI/CD integration best practices.
Explanation
Maven project structure follows convention over configuration. Standard directory layout:
```
project/
├── pom.xml
├── src/
│ ├── main/
│ │ ├── java/ # Source code
│ │ ├── resources/ # Config files
│ │ └── webapp/ # Web resources (for WAR)
│ └── test/
│ ├── java/ # Test code
│ └── resources/ # Test resources
└── target/ # Build output
```
pom.xml (Project Object Model) defines project configuration:
```xml
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>myapp</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>jar</packaging>
<properties>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.7.0</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
```
Maven lifecycle phases: validate (validate project correctness), compile (compile source code), test (run unit tests), package (create JAR/WAR), verify (run integration tests), install (install to local repository), deploy (deploy to remote repository). Each phase executes all previous phases.
Dependency management uses transitive dependencies (automatically includes dependencies of dependencies). Dependency scopes: compile (default, available everywhere), provided (available at compile but not included in package), runtime (needed at runtime but not compile), test (only for tests), system (like provided but specified via systemPath). Example:
```xml
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope> # Servlet container provides this
</dependency>
```
Dependency exclusions prevent transitive dependency issues:
```xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
```
Dependency management section defines versions centrally:
```xml
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.7.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
```
Plugins extend Maven functionality:
```xml
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.10.1</version>
<configuration>
<source>11</source>
<target>11</target>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
```
Repository configuration:
```xml
<repositories>
<repository>
<id>central</id>
<url>https://repo1.maven.org/maven2</url>
</repository>
<repository>
<id>company-repo</id>
<url>https://nexus.company.com/repository/maven-public/</url>
</repository>
</repositories>
<distributionManagement>
<repository>
<id>releases</id>
<url>https://nexus.company.com/repository/maven-releases/</url>
</repository>
<snapshotRepository>
<id>snapshots</id>
<url>https://nexus.company.com/repository/maven-snapshots/</url>
</snapshotRepository>
</distributionManagement>
```
CI/CD integration:
```yaml
# GitLab CI
build:
image: maven:3.8-jdk-11
script:
- mvn clean package
artifacts:
paths:
- target/*.jar
cache:
key: ${CI_COMMIT_REF_SLUG}
paths:
- .m2/repository
```
Settings.xml for credentials (~/.m2/settings.xml):
```xml
<settings>
<servers>
<server>
<id>releases</id>
<username>${env.NEXUS_USER}</username>
<password>${env.NEXUS_PASSWORD}</password>
</server>
</servers>
<mirrors>
<mirror>
<id>company-mirror</id>
<mirrorOf>*</mirrorOf>
<url>https://nexus.company.com/repository/maven-public/</url>
</mirror>
</mirrors>
</settings>
```
Best practices: use dependency management for version consistency, leverage Bill of Materials (BOM) for related dependencies, cache .m2/repository in CI/CD, use Maven wrapper for version consistency, skip tests during package if already run (mvn package -DskipTests), parallel builds (mvn -T 4 package), offline mode for faster builds with cached dependencies (mvn -o package). Understanding Maven enables efficient Java project automation.