@@ -15,6 +15,7 @@ Effective Maven usage involves robust dependency management via `<dependencyMana
1515- Rule 4: Use Build Profiles for Environment-Specific Configurations
1616- Rule 5: Keep POMs Readable and Maintainable
1717- Rule 6: Manage Repositories Explicitly
18+ - Rule 7: Centralize Version Management with Properties
1819
1920## Rule 1: Effective Dependency Management
2021
@@ -408,3 +409,156 @@ Description: Prefer dependencies from Maven Central. If custom repositories are
408409 </dependencies>
409410</project>
410411```
412+
413+ ## Rule 7: Centralize Version Management with Properties
414+
415+ Title: Use Properties to Manage Dependency and Plugin Versions
416+ 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`.
417+
418+ **Good example:**
419+
420+ ```xml
421+ <project>
422+ <modelVersion>4.0.0</modelVersion>
423+ <groupId>com.example</groupId>
424+ <artifactId>my-app</artifactId>
425+ <version>1.0.0</version>
426+
427+ <properties>
428+ <!-- Core build properties -->
429+ <java.version>17</java.version>
430+ <maven.version>3.9.10</maven.version>
431+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
432+ <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
433+
434+ <!-- Dependency versions -->
435+ <jackson.version>2.15.3</jackson.version>
436+ <junit.version>5.10.1</junit.version>
437+ <mockito.version>5.7.0</mockito.version>
438+ <logback.version>1.4.11</logback.version>
439+
440+ <!-- Maven plugin versions -->
441+ <maven-plugin-compiler.version>3.14.0</maven-plugin-compiler.version>
442+ <maven-plugin-surefire.version>3.5.3</maven-plugin-surefire.version>
443+ <maven-plugin-failsafe.version>3.5.3</maven-plugin-failsafe.version>
444+ <maven-plugin-enforcer.version>3.5.0</maven-plugin-enforcer.version>
445+
446+ <!-- Third-party plugin versions -->
447+ <maven-plugin-jacoco.version>0.8.13</maven-plugin-jacoco.version>
448+
449+ <!-- Quality thresholds -->
450+ <coverage.level>80</coverage.level>
451+ <mutation.level>70</mutation.level>
452+ </properties>
453+
454+ <dependencies>
455+ <dependency>
456+ <groupId>com.fasterxml.jackson.core</groupId>
457+ <artifactId>jackson-databind</artifactId>
458+ <version>${jackson.version}</version>
459+ </dependency>
460+ <dependency>
461+ <groupId>org.junit.jupiter</groupId>
462+ <artifactId>junit-jupiter-api</artifactId>
463+ <version>${junit.version}</version>
464+ <scope>test</scope>
465+ </dependency>
466+ <dependency>
467+ <groupId>org.mockito</groupId>
468+ <artifactId>mockito-core</artifactId>
469+ <version>${mockito.version}</version>
470+ <scope>test</scope>
471+ </dependency>
472+ </dependencies>
473+
474+ <build>
475+ <plugins>
476+ <plugin>
477+ <groupId>org.apache.maven.plugins</groupId>
478+ <artifactId>maven-compiler-plugin</artifactId>
479+ <version>${maven-plugin-compiler.version}</version>
480+ <configuration>
481+ <source>${java.version}</source>
482+ <target>${java.version}</target>
483+ </configuration>
484+ </plugin>
485+ <plugin>
486+ <groupId>org.apache.maven.plugins</groupId>
487+ <artifactId>maven-surefire-plugin</artifactId>
488+ <version>${maven-plugin-surefire.version}</version>
489+ </plugin>
490+ <plugin>
491+ <groupId>org.jacoco</groupId>
492+ <artifactId>jacoco-maven-plugin</artifactId>
493+ <version>${maven-plugin-jacoco.version}</version>
494+ </plugin>
495+ </plugins>
496+ </build>
497+ </project>
498+ ```
499+
500+ **Bad Example:**
501+
502+ ```xml
503+ <!-- Hardcoded versions scattered throughout the POM -->
504+ <project>
505+ <modelVersion>4.0.0</modelVersion>
506+ <groupId>com.example</groupId>
507+ <artifactId>my-app</artifactId>
508+ <version>1.0.0</version>
509+
510+ <properties>
511+ <java.version>17</java.version>
512+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
513+ </properties>
514+
515+ <dependencies>
516+ <dependency>
517+ <groupId>com.fasterxml.jackson.core</groupId>
518+ <artifactId>jackson-databind</artifactId>
519+ <version>2.15.3</version> <!-- Hardcoded version -->
520+ </dependency>
521+ <dependency>
522+ <groupId>com.fasterxml.jackson.core</groupId>
523+ <artifactId>jackson-core</artifactId>
524+ <version>2.15.2</version> <!-- Different version of same library family! -->
525+ </dependency>
526+ <dependency>
527+ <groupId>org.junit.jupiter</groupId>
528+ <artifactId>junit-jupiter-api</artifactId>
529+ <version>5.10.1</version> <!-- Hardcoded version -->
530+ <scope>test</scope>
531+ </dependency>
532+ <dependency>
533+ <groupId>org.junit.jupiter</groupId>
534+ <artifactId>junit-jupiter-engine</artifactId>
535+ <version>5.9.3</version> <!-- Different JUnit version! -->
536+ <scope>test</scope>
537+ </dependency>
538+ </dependencies>
539+
540+ <build>
541+ <plugins>
542+ <plugin>
543+ <groupId>org.apache.maven.plugins</groupId>
544+ <artifactId>maven-compiler-plugin</artifactId>
545+ <version>3.11.0</version> <!-- Hardcoded plugin version -->
546+ <configuration>
547+ <source>17</source> <!-- Hardcoded Java version instead of using property -->
548+ <target>17</target>
549+ </configuration>
550+ </plugin>
551+ <plugin>
552+ <groupId>org.apache.maven.plugins</groupId>
553+ <artifactId>maven-surefire-plugin</artifactId>
554+ <version>3.2.2</version> <!-- Hardcoded plugin version -->
555+ </plugin>
556+ <plugin>
557+ <groupId>org.jacoco</groupId>
558+ <artifactId>jacoco-maven-plugin</artifactId>
559+ <version>0.8.10</version> <!-- Hardcoded and potentially outdated -->
560+ </plugin>
561+ </plugins>
562+ </build>
563+ </project>
564+ ```
0 commit comments