maven — Cursor rule: what it does, how to install
Guides Cursor to generate clean Maven build configurations and enforce narrow dependency scopes across Java projects.
.cursor/rules/maven.mdcWhat maven does
This rule targets **/*.java files. It instructs the assistant to avoid duplicating versions across modules by centralizing dependency versions and plugin configurations inside <dependencyManagement> and <pluginManagement> in a parent POM or BOM.
It restricts dependency scopes to the narrowest option (compile, provided, runtime, or test), keeping test artifacts out of application classpaths. The rule also mandates explicit <exclusions> for conflicting transitive dependencies instead of trusting Maven's nearest-definition resolution.
For team consistency, the guide insists on ./mvnw over arbitrary local Maven binaries. Environment settings belong in environment variables rather than inside build profiles.
What it helps with
- centralize dependencies inside a parent
<dependencyManagement>block - isolate test libraries by declaring the
testscope explicitly - eliminate conflicting transitive dependencies with
<exclusions> - standardize build execution using
./mvnw
Example prompts for the agent
- Set up a parent POM with dependencyManagement for this multi-module build
- Add the JUnit Jupiter dependency with the correct test scope to pom.xml
- Exclude an incompatible transitive library from this dependency
How to install maven
Manually: put the files in place
.cursor/rules/maven.mdcFrontmatter: description, globs, alwaysApply
Manually: put the files in place
.claude/rules/maven.mdThe paths frontmatter field limits the files: move globs from the source into paths
AGENTS.md
Codex reads AGENTS.md: paste the rule text there
Manually: put the files in place
.github/instructions/maven.instructions.mdThe applyTo field sets which files it applies to: move globs from the source into applyTo
Manually: put the files in place
.devin/rules/maven.mdManually: put the files in place
.clinerules/maven.mdStep by step, with commands for each platform: Cursor rules: .mdc files, four modes and what replaced .cursorrules
Questions about maven
How to install maven in Cursor?
Save the rule content to .cursor/rules/maven.mdc inside your project directory.
What does the maven rule do?
It steers Cursor toward clean Maven configuration patterns, including centralized version management, restrictive scopes, and exclusions for problematic dependencies.
Why does the rule recommend Maven Wrapper?
Generating a wrapper with mvn wrapper:wrapper locks the build tool version. Running ./mvnw keeps builds consistent across different developer machines and CI runners.
Source text
maven.mdc · CC0-1.0
---
description: This guide provides opinionated, actionable best practices for Maven projects, focusing on reproducible builds, efficient dependency management, and high code quality.
globs: **/*.java
---
# Maven Best Practices
Maven is the definitive build tool for modern Java. Adhere to these rules for consistent, maintainable, and high-quality projects.
## Code Organization and Structure
### Centralize Configuration with a Parent POM/BOM
Always use a parent POM (or Bill of Materials - BOM) to define shared properties, plugin versions, and a `<dependencyManagement>` section. This guarantees consistent library versions and build behavior across all modules.
❌ BAD: Duplicating dependency versions and plugin configurations in every child `pom.xml`.
```xml
<!-- child-module/pom.xml -->
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>3.2.0</version> <!-- Hardcoded, duplicated -->
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.11.0</version> <!-- Hardcoded, duplicated -->
<configuration><release>17</release></configuration>
</plugin>
</plugins>
</build>
```
✅ GOOD: Define a parent POM with `<dependencyManagement>` and `<pluginManagement>`. Child modules inherit these.
```xml
<!-- parent/pom.xml -->
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.mycompany</groupId>
<artifactId>my-parent</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>pom</packaging>
<properties>
<java.version>17</java.version>
<spring-boot.version>3.2.0</spring-boot.version>
<maven.compiler.plugin.version>3.11.0</maven.compiler.plugin.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>${maven.compiler.plugin.version}</version>
<configuration><release>${java.version}</release></configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
<!-- child-module/pom.xml -->
<project>
<parent>
<groupId>com.mycompany</groupId>
<artifactId>my-parent</artifactId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>my-child-module</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<!-- Version inherited from parent's dependencyManagement -->
</dependency>
</dependencies>
</project>
```
## Common Patterns and Anti-patterns
### Declare the Narrowest Possible Dependency Scope
Limit dependency transitivity and classpath bloat by using the most restrictive scope (`compile`, `provided`, `runtime`, `test`).
❌ BAD: Using `compile` scope for everything, including test-only dependencies.
```xml
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.11.0</version>
<!-- Missing scope, defaults to compile -->
</dependency>
```
✅ GOOD: Explicitly define scopes.
* `compile` (default): Available in all classpaths, propagated to dependents. For core libraries.
* `provided`: Expected to be provided by JDK or container at runtime. For Servlet API, Java EE APIs.
* `runtime`: Not needed for compilation, but for execution. For JDBC drivers.
* `test`: Only for test compilation and execution. For JUnit, Mockito.
```xml
<dependencies>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<scope>test</scope> <!-- Correct scope for testing -->
</dependency>
<dependency>
<groupId>jakarta.servlet</groupId>
<artifactId>jakarta.servlet-api</artifactId>
<version>6.0.0</version>
<scope>provided</scope> <!-- Provided by web container -->
</dependency>
</dependencies>
```
### Manage Transitive Dependencies with Exclusions
Prevent unwanted or conflicting transitive dependencies from polluting your classpath.
❌ BAD: Relying on Maven's "nearest definition" for conflicting transitive dependencies, leading to unpredictable builds or runtime issues.
```xml
<!-- Project A depends on B (which depends on D 1.0) and C (which depends on D 2.0) -->
<!-- Maven might pick D 1.0 or D 2.0 based on declaration order/depth -->
<dependency>
<groupId>com.example</groupId>
<artifactId>library-b</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>com.example</groupId>
<artifactId>library-c</artifactId>
<version>1.0</version>
</dependency>
```
✅ GOOD: Explicitly exclude problematic transitive dependencies and declare the desired version directly.
```xml
<dependencies>
<dependency>
<groupId>com.example</groupId>
<artifactId>library-b</artifactId>
<version>1.0</version>
<exclusions>
<exclusion>
<groupId>com.example</groupId>
<artifactId>dependency-d</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.example</groupId>
<artifactId>library-c</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>com.example</groupId>
<artifactId>dependency-d</artifactId>
<version>2.0</version> <!-- Explicitly declare the desired version -->
</dependency>
</dependencies>
```
## Performance Considerations
### Use Maven Wrapper for Consistent Builds
Ensure all developers and CI/CD pipelines use the exact same Maven version, preventing "works on my machine" issues related to Maven itself.
✅ GOOD: Include Maven Wrapper in your project.
```bash
mvn wrapper:wrapper
```
Then, use `./mvnw` (or `mvnw.cmd` on Windows) instead of `mvn`.
```bash
./mvnw clean install
```
## Common Pitfalls and Gotchas
### Avoid Over-reliance on Maven Profiles for Environment Configuration
Modern applications should be environment-agnostic (12-factor app principles). Use external configuration (environment variables, configuration servers) for environment-specific settings, not Maven profiles.
❌ BAD: Using profiles to inject environment-specific database URLs or API keys.
```xml
<!-- profile in pom.xml -->
<profiles>
<profile>
<id>dev</id>
<properties>
<db.url>jdbc:h2:mem:devdb</db.url>
</properties>
</profile>
<profile>
<id>prod</id>
<properties>
<db.url>jdbc:postgresql://prod-db:5432/appdb</db.url>
</properties>
</profile>
</profiles>
```
✅ GOOD: Keep application configuration external to the build. Maven profiles are acceptable for *build process* variations (e.g., different test suites, packaging types), but not runtime environment configuration.
## Testing Approaches
### Integrate Static Analysis Plugins
Enforce coding standards and identify potential issues early by integrating static analysis tools like Checkstyle, SpotBugs, or PMD into the Maven build lifecycle (e.g., `verify` phase).
✅ GOOD: Configure static analysis plugins in your parent POM's `<build>` section.
```xml
<!-- parent/pom.xml -->
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
<version>3.3.1</version>
<executions>
<execution>
<id>validate</id>
<phase>validate</phase>
<goals>
<goal>check</goal>
</goals>
<configuration>
<configLocation>checkstyle.xml</configLocation>
<failsOnError>true</failsOnError>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>com.github.spotbugs</groupId>
<artifactId>spotbugs-maven-plugin</artifactId>
<version>4.8.3.0</version>
<executions>
<execution>
<id>analyze</id>
<phase>verify</phase>
<goals>
<goal>check</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</pluginManagement>
</build>
```
© sanjeed5 · CC0-1.0 · sanjeed5/awesome-cursor-rules-mdc