
110 Java Maven Best Practices
- 260 installs
- 424 repo stars
- Updated August 2, 2026
- jabrena/cursor-rules-java
Refactor and harden a Maven pom.xml with dependencyManagement, BOMs, profiles, and maintainable plugin conventions.
About
110-java-maven-best-practices is a Cursor-oriented agent skill for solo Java developers who need to improve an existing Maven pom.xml without drift, version conflicts, or unreadable plugin sprawl. It positions you as a senior engineer applying Maven’s core principles: convention over configuration, declarative POM models, reproducible dependency graphs, and lifecycle-aware builds. Concrete guidance covers dependencyManagement and BOM imports, adhering to src/main/java layout, hoisting versions into properties, managing plugins in one place, and using profiles for environment-specific settings while keeping custom repositories explicit and rare. Invoke it when a greenfield POM is messy, when transitive dependency hell appears, or before onboarding collaborators who must understand your build at a glance. It does not replace domain coding skills—it sharpens the build contract your backend depends on.
- dependencyManagement sections and BOM imports for consistent versions
- Standard directory layout and convention-over-configuration alignment
- Centralized plugin management and environment-specific Maven profiles
- Readable POM structure with properties for version centralization
- Guidance to minimize custom repositories and prefer repository managers
110 Java Maven Best Practices by the numbers
- 260 all-time installs (skills.sh)
- +3 installs in the week ending Aug 2, 2026 (Skillselion tracking)
- Ranked #19 of 89 Java & JVM skills by installs in the Skillselion catalog
- Security screen: LOW risk (skills.sh audit)
- Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/jabrena/cursor-rules-java --skill 110-java-maven-best-practicesAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 260 |
|---|---|
| repo stars | ★ 424 |
| Security audit | 3 / 3 scanners passed |
| Last updated | August 2, 2026 |
| Repository | jabrena/cursor-rules-java ↗ |
What it does
Refactor and harden a Maven pom.xml with dependencyManagement, BOMs, profiles, and maintainable plugin conventions.
Files
Maven Best Practices
Improve Maven POM configuration using industry-standard best practices.
What is covered in this Skill?
- Dependency management via
<dependencyManagement>and BOMs - Standard directory layout (
src/main/java,src/test/java) - Centralized plugin management
- Build profiles for environment-specific settings
- Readable POM structure with version properties
- Explicit repository declaration
- Version centralization
- Multi-module project structure with proper inheritance
- Cross-module version consistency
- Multi-module scope: After reading the root
pom.xml, check for a<modules>section. If present, read every child module'spom.xmlbefore making any recommendations. - Check each child for hardcoded versions that duplicate parent
<dependencyManagement>, redundant<pluginManagement>blocks, properties that should be centralized, and version drift across sibling modules.
Constraints
Before applying Maven best practices recommendations, ensure the project is in a valid state by running Maven validation. This helps identify any existing configuration issues that need to be resolved first. For multi-module projects, scope analysis must cover every child module POM — not just the root.
- MANDATORY: Run
./mvnw validateormvn validatebefore applying any Maven best practices recommendations - VERIFY: Ensure all validation errors are resolved before proceeding with POM modifications
- SAFETY: If validation fails, do not continue and ask the user to fix the issues before continuing
- MULTI-MODULE DISCOVERY: After reading the root
pom.xml, check whether it contains a<modules>section. If it does, read every child module'spom.xmlbefore making any recommendations — analysis scope is the full module tree, not only the root - CROSS-MODULE SCOPE: When child modules exist, check each one for: hardcoded dependency versions that duplicate
<dependencyManagement>in the parent, plugin configurations that duplicate<pluginManagement>, properties that should be centralized in the parent, and version drift (same artifact declared at different versions across sibling modules) - BEFORE APPLYING: Read the reference for detailed examples, good/bad patterns, and constraints
When to use this skill
- Review pom.xml to improve it
- Apply Maven best practices to pom.xml
- Improve Maven POM configuration
Workflow
1. Validate project before recommendations
Run ./mvnw validate or mvn validate and stop if validation fails.
2. Read reference and analyze root POM
Read references/110-java-maven-best-practices.md, then inspect root pom.xml structure, dependency management, plugin management, properties, and profiles.
3. Expand to full module tree when present
If root has a <modules> section, read every child pom.xml and evaluate cross-module duplication, centralization opportunities, and version drift.
4. Provide prioritized best-practice recommendations
Propose concrete, safe improvements aligned with Maven best practices and full-module findings.
Reference
For detailed guidance, examples, and constraints, see references/110-java-maven-best-practices.md.
Maven Best Practices
Role
You are a Senior software engineer with extensive experience in Java software development
Goal
Effective Maven usage involves robust dependency management via <dependencyManagement> and BOMs, adherence to the standard directory layout, and centralized plugin management. Build profiles should be used for environment-specific configurations. POMs must be kept readable and maintainable with logical structure and properties for versions. Custom repositories should be declared explicitly and their use minimized, preferably managed via a central repository manager.
Core Principles Behind Maven
Maven is built on several foundational principles that guide its design and usage:
1. Convention Over Configuration: Maven follows the principle that sensible defaults should be provided so developers don't need to specify everything explicitly. The standard directory layout (src/main/java, src/test/java) exemplifies this - Maven knows where to find source code without explicit configuration. 2. Declarative Project Model: Projects are described through a declarative Project Object Model (POM) rather than imperative build scripts. You declare what you want (dependencies, plugins, goals) rather than how to achieve it. 3. Dependency Management and Transitive Dependencies: Maven automatically resolves and downloads dependencies and their transitive dependencies, creating a complete classpath. The dependency management system prevents version conflicts through nearest-wins and dependency mediation strategies. 4. Build Lifecycle and Phases: Maven follows a well-defined build lifecycle with standard phases (validate, compile, test, package, install, deploy). This provides predictability and consistency across all Maven projects. 5. Plugin-Based Architecture: All Maven functionality is provided through plugins. Core operations like compilation, testing, and packaging are all plugin-based, making Maven extensible and modular. 6. Repository-Centric: Maven uses repositories (local, central, remote) as the primary mechanism for sharing and reusing artifacts. This enables easy sharing of libraries and promotes reuse across the Java ecosystem. 7. Coordinate System: Every artifact is uniquely identified by coordinates (groupId, artifactId, version), enabling precise dependency specification and avoiding JAR hell. 8. Inheritance and Aggregation: Projects can inherit from parent POMs (inheritance) and contain multiple modules (aggregation), enabling both shared configuration and multi-module builds.
In multi-module projects, best-practices analysis must extend beyond the root POM to cover all child module POMs. This includes verifying the correctness of the full inheritance chain, detecting cross-module version drift, eliminating redundant <dependencyManagement> or <pluginManagement> blocks in child modules, and ensuring that shared properties remain centralized in the parent or a dedicated BOM module.
Constraints
Before applying Maven best practices recommendations, ensure the project is in a valid state by running Maven validation. This helps identify any existing configuration issues that need to be resolved first. For multi-module projects, scope analysis must cover every child module POM — not just the root.
- MANDATORY: Run
./mvnw validateormvn validatebefore applying any Maven best practices recommendations - VERIFY: Ensure all validation errors are resolved before proceeding with POM modifications
- SAFETY: If validation fails, not continue and ask the user to fix the issues before continuing
- MULTI-MODULE DISCOVERY: After reading the root
pom.xml, check whether it contains a<modules>section. If it does, read every child module'spom.xmlbefore making any recommendations — analysis scope is the full module tree, not only the root - CROSS-MODULE SCOPE: When child modules exist, check each one for: hardcoded dependency versions that duplicate
<dependencyManagement>in the parent, plugin configurations that duplicate<pluginManagement>, properties that should be centralized in the parent, and version drift (same artifact declared at different versions across sibling modules)
Examples
Table of contents
- Example 1: Effective Dependency Management
- Example 2: Standard Directory Layout
- Example 3: Plugin Management and Configuration
- Example 4: Use Build Profiles for Environment-Specific Configurations
- Example 5: Keep POMs Readable and Maintainable
- Example 6: Manage Repositories Explicitly
- Example 7: Centralize Version Management with Properties
- Example 8: Multi-Module Project Structure
- Example 9: Cross-Module Version Consistency
Example 1: Effective Dependency Management
Title: Manage Dependencies Effectively using dependencyManagement and BOMs Description: Use the <dependencyManagement> section in parent POMs or import Bill of Materials (BOMs) to centralize and control dependency versions. This helps avoid version conflicts and ensures consistency across multi-module projects. Avoid hardcoding versions directly in <dependencies> when managed elsewhere.
Good example:
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>my-parent</artifactId>
<version>1.0.0</version>
<packaging>pom</packaging>
<properties>
<spring.version>5.3.23</spring.version>
<junit.version>5.9.0</junit.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.7.5</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
</project>
<project>
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.example</groupId>
<artifactId>my-parent</artifactId>
<version>1.0.0</version>
</parent>
<artifactId>my-module</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
</dependency>
</dependencies>
</project>
Bad example:
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>my-other-module</artifactId>
<version>1.0.0</version>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.20</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
Example 2: Standard Directory Layout
Title: Adhere to the Standard Directory Layout Description: Follow Maven's convention for directory structure (src/main/java, src/main/resources, src/test/java, src/test/resources, etc.). This makes projects easier to understand and build, as Maven relies on these defaults.
Good example:
my-app/
├── pom.xml
└── src/
├── main/
│ ├── java/
│ │ └── com/example/myapp/App.java
│ └── resources/
│ └── application.properties
└── test/
├── java/
│ └── com/example/myapp/AppTest.java
└── resources/
└── test-data.xml
Bad example:
my-app/
├── pom.xml
├── sources/
│ └── com/example/myapp/App.java
├── res/
│ └── config.properties
└── tests/
└── com/example/myapp/AppTest.java
Example 3: Plugin Management and Configuration
Title: Manage Plugin Versions and Configurations Centrally Description: Use <pluginManagement> in a parent POM to define plugin versions and common configurations. Child POMs can then use the plugins without specifying versions, ensuring consistency. Override configurations in child POMs only when necessary.
Good example:
<project>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.10.1</version>
<configuration>
<source>17</source>
<target>17</target>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
<project>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
Bad example:
<project>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>11</source>
<target>11</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
Example 4: Use Build Profiles for Environment-Specific Configurations
Title: Employ Build Profiles for Environment-Specific Settings Description: Use Maven profiles to customize build settings for different environments (e.g., dev, test, prod) or other conditional scenarios. This can include different dependencies, plugin configurations, or properties. Activate profiles via command line, OS, JDK, or file presence.
Good example:
<project>
<profiles>
<profile>
<id>dev</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<database.url>jdbc:h2:mem:devdb</database.url>
</properties>
</profile>
<profile>
<id>prod</id>
<properties>
<database.url>jdbc:postgresql://prodserver/mydb</database.url>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>3.1.0</version>
<executions>
<execution>
<phase>package</phase>
<goals><goal>run</goal></goals>
<configuration>
<target>
<echo>Simulating minification for prod</echo>
</target>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>
Run with: mvn clean install -P prod
Bad example:
<project>
<properties>
<database.url>jdbc:postgresql://prodserver/mydb</database.url>
</properties>
</project>
Example 5: Keep POMs Readable and Maintainable
Title: Structure POMs Logically for Readability Description: Organize your pom.xml sections in a consistent order (e.g., project coordinates, parent, properties, dependencyManagement, dependencies, build, profiles, repositories). Use properties for recurring versions or values. Add comments for complex configurations.
Good example:
<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">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>my-app</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>My Application</name>
<description>A sample application.</description>
<properties>
<java.version>17</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<some.library.version>2.5.1</some.library.version>
</properties>
<dependencyManagement>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.some.library</groupId>
<artifactId>some-library-core</artifactId>
<version>${some.library.version}</version>
</dependency>
</dependencies>
<build>
</build>
</project>
Bad example:
<project>
<dependencies>
<dependency>
<groupId>org.some.library</groupId>
<artifactId>some-library-core</artifactId>
<version>2.5.1</version>
</dependency>
</dependencies>
<modelVersion>4.0.0</modelVersion>
<build>
</build>
<groupId>com.example</groupId>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<artifactId>my-app</artifactId>
<version>1.0.0-SNAPSHOT</version>
</project>
Example 6: Manage Repositories Explicitly
Title: Declare Custom Repositories Explicitly and Minimize Their Use Description: Prefer dependencies from Maven Central. If custom repositories are necessary, declare them in the <repositories> section and <pluginRepositories> for plugins. It's often better to manage these in a company-wide Nexus/Artifactory instance configured in settings.xml rather than per-project POMs. Avoid relying on transitive repositories.
Good example:
<project>
<repositories>
<repository>
<id>my-internal-repo</id>
<url>https://nexus.example.com/repository/maven-releases/</url>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>my-internal-plugins</id>
<url>https://nexus.example.com/repository/maven-plugins/</url>
</pluginRepository>
</pluginRepositories>
</project>
Bad example:
<project>
<dependencies>
<dependency>
<groupId>com.internal.stuff</groupId>
<artifactId>internal-lib</artifactId>
<version>1.0</version>
</dependency>
</dependencies>
</project>
Example 7: Centralize Version Management with Properties
Title: Use Properties to Manage Dependency and Plugin Versions Description: Define all dependency and plugin versions in the <properties> section rather than hardcoding them throughout the POM. This centralizes version management, makes updates easier, reduces duplication, and helps maintain consistency across related dependencies. Use consistent property naming conventions: maven-plugin-[name].version for Maven plugins, simple names like [library].version for dependencies, and descriptive names for quality thresholds like coverage.level.
Good example:
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>my-app</artifactId>
<version>1.0.0</version>
<properties>
<java.version>17</java.version>
<maven.version>3.9.10</maven.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<jackson.version>2.15.3</jackson.version>
<junit.version>5.10.1</junit.version>
<mockito.version>5.7.0</mockito.version>
<logback.version>1.4.11</logback.version>
<maven-plugin-compiler.version>3.14.0</maven-plugin-compiler.version>
<maven-plugin-surefire.version>3.5.3</maven-plugin-surefire.version>
<maven-plugin-failsafe.version>3.5.3</maven-plugin-failsafe.version>
<maven-plugin-enforcer.version>3.5.0</maven-plugin-enforcer.version>
<maven-plugin-jacoco.version>0.8.13</maven-plugin-jacoco.version>
<coverage.level>80</coverage.level>
<mutation.level>70</mutation.level>
</properties>
<dependencies>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>${mockito.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>${maven-plugin-compiler.version}</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>${maven-plugin-surefire.version}</version>
</plugin>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>${maven-plugin-jacoco.version}</version>
</plugin>
</plugins>
</build>
</project>
Bad example:
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>my-app</artifactId>
<version>1.0.0</version>
<properties>
<java.version>17</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.15.3</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.15.2</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.10.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>5.9.3</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.11.0</version>
<configuration>
<source>17</source>
<target>17</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.2.2</version>
</plugin>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.10</version>
</plugin>
</plugins>
</build>
</project>
Example 8: Multi-Module Project Structure
Title: Organize a Multi-Module Build with a Root Aggregator POM and Proper Inheritance Description: In a multi-module project the root POM acts as both aggregator (via <modules>) and parent (via inheritance). All shared dependency versions and plugin configurations belong in the root POM's <dependencyManagement> and <pluginManagement> sections. Child module POMs declare <parent> and reference managed artifacts without specifying versions. A dedicated BOM module can be introduced to decouple version management from build orchestration in large projects.
Good example:
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>my-parent</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>pom</packaging>
<modules>
<module>my-api</module>
<module>my-service</module>
<module>my-web</module>
</modules>
<properties>
<java.version>21</java.version>
<jackson.version>2.17.0</jackson.version>
<junit.version>5.11.0</junit.version>
<maven-plugin-compiler.version>3.14.0</maven-plugin-compiler.version>
<maven-plugin-surefire.version>3.5.3</maven-plugin-surefire.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.example</groupId>
<artifactId>my-api</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>${maven-plugin-compiler.version}</version>
<configuration>
<release>${java.version}</release>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>${maven-plugin-surefire.version}</version>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
<project>
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.example</groupId>
<artifactId>my-parent</artifactId>
<version>1.0.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>my-service</artifactId>
<dependencies>
<dependency>
<groupId>com.example</groupId>
<artifactId>my-api</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
</dependency>
</dependencies>
</project>
Bad example:
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>my-parent</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>pom</packaging>
</project>
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>my-service</artifactId>
<version>1.0.0-SNAPSHOT</version>
<parent>
<groupId>com.example</groupId>
<artifactId>my-parent</artifactId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.16.0</version>
</dependency>
</dependencies>
</dependencyManagement>
</project>
Example 9: Cross-Module Version Consistency
Title: Detect and Fix Version Drift Across Sibling Modules Description: Version drift occurs when the same artifact is declared at different versions in sibling module POMs. This leads to non-reproducible builds and subtle runtime errors. The fix is to move all version declarations into the root POM's <dependencyManagement> (or a BOM module) and remove versions from every child POM. When performing multi-module analysis, read all sibling pom.xml files and compare declared dependency versions before recommending changes.
Good example:
<project>
<properties>
<logback.version>1.5.6</logback.version>
<slf4j.version>2.0.13</slf4j.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>${logback.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
</project>
<dependencies>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
</dependency>
</dependencies>
<dependencies>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
</dependency>
</dependencies>
Bad example:
<dependencies>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.4.11</version>
</dependency>
</dependencies>
<dependencies>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.5.6</version>
</dependency>
</dependencies>
Output Format
- DISCOVER the full project scope before analysis: read the root
pom.xmland check for a<modules>section; if present, read every child module'spom.xmlrecursively. List all discovered modules and their paths at the start of the response so the user knows the analysis covers the complete build - ANALYZE Maven POM files to identify specific best practices violations and categorize them by impact (CRITICAL, MAINTENANCE, PERFORMANCE, STRUCTURE) and area (dependency management, plugin configuration, project structure, repository management, version control)
- CATEGORIZE Maven configuration improvements found: Dependency Management Issues (missing dependencyManagement vs centralized version control, hardcoded versions vs property-based management, version conflicts vs resolution strategies, unused dependencies vs clean dependency trees), Plugin Configuration Problems (outdated versions vs current releases, missing configurations vs optimal settings, suboptimal configurations vs performance-tuned setups), Project Structure Opportunities (non-standard layouts vs Maven conventions, poor POM organization vs structured sections, missing properties vs centralized configuration)
- APPLY Maven best practices directly by implementing the most appropriate improvements for each identified issue: Introduce dependencyManagement sections for version centralization, extract version properties for consistency, configure essential plugins with optimal settings, organize POM sections following Maven conventions, add missing repository declarations, optimize dependency scopes, and eliminate unused dependencies through analysis
- IMPLEMENT comprehensive Maven configuration optimization using proven patterns: Establish centralized dependency management through BOMs or parent POMs, standardize plugin versions and configurations across modules, organize POM structure with clear sections (properties, dependencyManagement, dependencies, build), implement security best practices for repositories, apply dependency scope optimization, and integrate build lifecycle enhancements
- REFACTOR Maven configuration systematically following the improvement roadmap: First centralize version management through properties and dependencyManagement, then standardize plugin configurations with current versions, organize POM structure following Maven conventions, optimize dependency scopes and eliminate unused dependencies, secure repository configurations, and enhance build profiles for different environments
- EXPLAIN the applied Maven improvements and their benefits: Build reliability enhancements through centralized dependency management, maintenance simplification via property-based versioning, performance improvements from optimized plugin configurations, security strengthening through proper repository management, and development productivity gains from standardized build practices
- VALIDATE that all applied Maven changes compile successfully, maintain existing build behavior, preserve dependency compatibility, follow Maven best practices, and achieve the intended build improvements through comprehensive testing and verification
Safeguards
- MANDATORY: Analyze existing POM configuration before making any changes
- NEVER remove or replace existing plugins - only add new plugins that don't already exist
- NEVER remove or replace existing properties - only add new properties that don't conflict
- ASK USER before overriding any existing configuration element
- Verify changes with the command:
./mvnw clean verify - Preserve existing dependency versions unless explicitly requested to update
- Maintain backward compatibility with existing build process
- MULTI-MODULE SCOPE: When root POM contains
<modules>, always read and analyze ALL child module POMs before making any recommendations — never base advice on the root POM alone - VALIDATE ALL MODULES: After any change to the root or a child POM in a multi-module project, run
./mvnw clean verifyfrom the project root to confirm the full reactor build still passes - PRESERVE MODULE OVERRIDES: Some child modules intentionally override parent-managed versions or plugin configurations for valid reasons (e.g., a module requiring a different Java release). Before removing an override from a child POM, confirm with the user that the override is unintentional
Related skills
FAQ
Is 110 Java Maven Best Practices safe to install?
skills.sh reports 3 of 3 security scanners passed. Review the Security Audits panel on this page before installing in production.