包详细信息

@jnxplus/nx-maven

gridatek34.1kMIT1.22.0

npm version

nx, nx-workspace, nx-plugin, java

自述文件

@jnxplus/nx-maven

npm version

This plugin adds Maven multi-module capabilities to Nx workspace.

Quick Start

Get started with nx-maven in 5 steps:

# 1. Install the plugin
npm install --save-dev @jnxplus/nx-maven

# 2. Initialize workspace with Maven support (Java 17 + Spring Boot Parent POM)
nx generate @jnxplus/nx-maven:init --javaVersion 17 --dependencyManagement spring-boot-parent-pom

# 3. Generate a library
nx generate @jnxplus/nx-maven:library my-lib --framework spring-boot --directory libs

# 4. Generate an application that uses the library
nx generate @jnxplus/nx-maven:application my-app --framework spring-boot --projects my-lib --directory apps

# 5. Serve the application
nx serve my-app

Supported versions

@jnxplus/nx-maven Nx Spring Boot Quarkus Micronaut
1.x.x >= 19 3.x.x 3.x.x 4.x.x
0.x.x >= 17 & <= 18 3.x.x 3.x.x 4.x.x

Getting Started

0. Prerequisites

@jnxplus/nx-maven requires a Java 17 or higher Runtime Environment and the current Long Term Support (LTS) version of node.js.

1. Install the plugin

In the Nx workspace root folder, run this command to install the plugin :

npm install --save-dev @jnxplus/nx-maven

2. Init workspace with Maven support

The following command adds Maven support (Maven wrapper and config files) to the workspace. This only needs to be performed once per workspace.

nx generate @jnxplus/nx-maven:init

You will be prompted for:

  • Java version (default: none) - Options: none, 17, 21, or 25
  • Dependency management strategy (default: none) - Options:
    • spring-boot-parent-pom - Spring Boot Parent POM
    • spring-boot-bom - Spring Boot BOM (Bill of Materials)
    • quarkus-bom - Quarkus BOM
    • micronaut-parent-pom - Micronaut Parent POM
    • micronaut-bom - Micronaut BOM
    • none - Configure manually later in a parent project (for advanced use cases)

Additional options:

  • --mavenRootDirectory - Subdirectory for Maven files (default: workspace root). See Maven Root Directory section.
  • --aggregatorProjectGroupId - GroupId for root aggregator project (default: com.example)
  • --aggregatorProjectName - Name for root aggregator project (default: root-aggregator-project)
  • --aggregatorProjectVersion - Version for root aggregator project (default: 0.0.1-SNAPSHOT)
  • --localRepoRelativePath - Path to Maven local repository where dependencies are stored, relative to mavenRootDirectory (default: .m2/repository). Must be a subfolder within the workspace so Nx can cache and restore dependencies between builds
  • --skipWrapper - Skip generating Maven wrapper (default: false)
  • --formatter - Code formatter to use: prettier or none (default: prettier)

Important: Maven Root Directory

By default, Maven files (wrapper, config, and projects) are placed at the workspace root. However, you can specify a subdirectory using the --mavenRootDirectory option:

nx generate @jnxplus/nx-maven:init --mavenRootDirectory maven

This creates the following structure:

workspace-root/
├── maven/                   # Maven root directory
│   ├── .mvn/                # Maven wrapper config
│   ├── mvnw, mvnw.cmd       # Maven wrapper scripts
│   ├── pom.xml              # Root aggregator POM
│   ├── .m2/repository/      # Local Maven repository
│   └── my-app/              # Your projects
│       └── pom.xml
├── apps/                    # Other Nx apps (non-Maven)
├── libs/                    # Other Nx libs (non-Maven)
└── package.json

When to use mavenRootDirectory:

  • Monorepo organization - Keep Maven projects isolated in their own directory
  • Better Nx caching - Separating Maven files improves Nx cache calculations and project graph performance

When to skip mavenRootDirectory (use root):

  • Simpler structure - Fewer nested directories
  • Hybrid workspaces - Mix Maven projects with other technologies (Node.js, Python, etc.) at the root level

Note: Once set during init, the mavenRootDirectory should remain consistent for all Maven projects in the workspace.

3. Generate a parent project (optional)

Parent projects help organize your applications and libraries with shared dependency management. Use parent projects when you need custom dependency management, want to organize projects into logical groups, or need to support multiple frameworks in your workspace.

nx generate @jnxplus/nx-maven:parent-project my-parent-project

Key options:

  • --javaVersion - Java version (17, 21, 25, or none)
  • --dependencyManagement - Dependency management strategy (same options as init)
  • --language - Language for sub-projects: java, kotlin, or java-kotlin
  • --directory - Directory where the project will be created (default: libs)
  • --parentProject - Parent project to inherit from (for nested parent projects)
  • --aggregatorProject - Aggregator project that manages a group of submodules

4. Generate applications and libraries

Generate an application

nx generate @jnxplus/nx-maven:application my-app

Key options:

  • --framework - Framework to use: spring-boot, quarkus, micronaut, or none
  • --language - Language: java or kotlin (default: java)
  • --parentProject - Parent project to use (uses root aggregator project if not specified)
  • --port - Server port for the application
  • --packaging - Packaging type: jar or war (default: jar)
  • --minimal - Generate minimal application without starter code
  • --groupId - Maven groupId (default: com.example)
  • --projectVersion - Maven version (default: 0.0.1-SNAPSHOT)
  • --directory - Directory where the project will be created (default: apps, e.g., backend creates at backend/my-app, apps/backend creates at apps/backend/my-app)
  • --simpleName - Don't include the directory in the project name (default: true)
  • --simplePackageName - Don't include the directory in the package name (default: true)
  • --tags - Tags for the project (comma-separated)

Generate a library

nx generate @jnxplus/nx-maven:library my-lib

Key options:

  • --framework - Framework to use: spring-boot, quarkus, micronaut, or none
  • --language - Language: java or kotlin (default: java)
  • --parentProject - Parent project to use (uses root aggregator project if not specified)
  • --projects - Projects that will use this library (comma-separated)
  • --skipStarterCode - Skip generating starter code
  • --groupId - Maven groupId (default: com.example)
  • --projectVersion - Maven version (default: 0.0.1-SNAPSHOT)
  • --directory - Directory where the project will be created (default: libs, e.g., backend creates at backend/my-lib, libs/backend creates at libs/backend/my-lib)
  • --simpleName - Don't include the directory in the project name (default: true)
  • --simplePackageName - Don't include the directory in the package name (default: true)
  • --tags - Tags for the project (comma-separated)

Example with directory:

# Creates project at: backend/my-lib
# Project name (with simpleName=true): my-lib
# Package name (with simplePackageName=true): com.example.mylib
nx generate @jnxplus/nx-maven:library my-lib --directory backend

# Creates project at: backend/my-lib
# Project name (with simpleName=false): backend-my-lib
# Package name (with simplePackageName=false): com.example.backend.mylib
nx generate @jnxplus/nx-maven:library my-lib --directory backend --simpleName false --simplePackageName false

5. Common tasks

Action Command
Build a project nx build my-project
Serve an application nx serve my-app
Test a project nx test my-project
Build a Docker image nx build-image my-app
Run custom Maven task nx run-task my-project --task="clean install"
Format a Java project nx format --projects my-project
Visualize project's dependency graph nx graph

6. Executors

nx-maven primarily uses the run-task executor for all Maven operations. Most targets (build, test, serve, etc.) internally use run-task to execute Maven commands.

run-task

Execute arbitrary Maven tasks on a project:

nx run-task my-project --task="clean install"

Options:

  • --task (required) - Maven task(s) to execute. Can be a string or array of strings
  • --outputDirLocalRepo - Sub-directory in Maven local repository where artifacts from install phase will be placed
  • --skipProject - Skip specifying the project with -pl :project flag
  • --cwd - Working directory for the command. Can be relative (to Maven root) or absolute
  • --skipExecutor - Skip executor execution (useful for conditional runs)

Examples:

# Single task
nx run-task my-app --task="clean package"

# Multiple tasks
nx run-task my-app --task="clean" --task="test" --task="package"

# With custom working directory
nx run-task my-app --task="compile" --cwd="custom-path"

# Skip project specification (run from Maven root)
nx run-task my-app --task="dependency:tree" --skipProject

quarkus-build-image

Build a Docker image for Quarkus applications:

nx build-image my-quarkus-app

Options:

  • --imageType - Image type to build (default: jvm). Options: jvm, native, etc.
  • --imageNamePrefix - Image name prefix (default: quarkus)
  • --imageNameSuffix - Image name suffix

Examples:

# Build JVM image (default)
nx build-image my-quarkus-app

# Build native image
nx build-image my-quarkus-app --imageType=native

# Custom image name
nx build-image my-quarkus-app --imageNamePrefix=myapp --imageNameSuffix=latest

Note: For Spring Boot and Micronaut applications, the build-image target uses the run-task executor with framework-specific commands:

  • Spring Boot: spring-boot:build-image
  • Micronaut: package -Dpackaging=docker

7. Plugin configuration

The init command configures the plugin in your nx.json file. You can customize these options to fit your workspace needs.

Example configuration with default values:

{
  "plugins": [
    {
      "plugin": "@jnxplus/nx-maven",
      "options": {
        "mavenRootDirectory": "nx-maven",
        "localRepoRelativePath": ".m2/repository",
        "buildTargetName": "build",
        "testTargetName": "test",
        "serveTargetName": "serve",
        "integrationTestTargetName": "integration-test",
        "buildImageTargetName": "build-image",
        "skipAggregatorProjectLinking": false,
        "skipProjectWithoutProjectJson": false
      }
    }
  ]
}

Available options:

  • mavenRootDirectory - Subdirectory for Maven files (default: workspace root)
  • localRepoRelativePath - Path to Maven local repository (default: .m2/repository)
  • buildTargetName - Name for the build target (default: build)
  • testTargetName - Name for the test target (default: test)
  • serveTargetName - Name for the serve target (default: serve)
  • integrationTestTargetName - Name for the integration test target (default: integration-test)
  • buildImageTargetName - Name for the build image target (default: build-image)
  • skipAggregatorProjectLinking - Skip linking aggregator projects in the dependency graph. Enable this when aggregator projects only contain <modules> declarations and all configuration is handled by parent projects. This improves Nx graph performance by reducing unnecessary dependency links. See Understanding parent projects vs aggregator projects for more details (default: false)
  • skipProjectWithoutProjectJson - Skip projects that don't have a project.json file (default: false)

8. Environment variables

You can customize nx-maven behavior using environment variables:

NX_MAVEN_CLI

Controls which Maven executable to use. Accepts: mvnw, mvn, or mvnd.

Examples:

# Linux/macOS
export NX_MAVEN_CLI=mvn
nx build my-app

# Windows (PowerShell)
$env:NX_MAVEN_CLI='mvnd'
nx build my-app

# Windows (CMD)
set NX_MAVEN_CLI=mvn
nx build my-app

Default behavior (when not set):

  • Uses mvnw (Maven wrapper) if it exists in the workspace
  • Falls back to mvn if wrapper doesn't exist

NX_MAVEN_CLI_OPTS

Pass additional arguments to Maven commands globally. Useful for CI/CD environments or consistent build settings.

Examples:

# Linux/macOS - disable transfer progress and enable verbose plugin validation
export NX_MAVEN_CLI_OPTS='--no-transfer-progress -Dmaven.plugin.validation=VERBOSE'
nx build my-app

# Windows (PowerShell) - run in batch mode
$env:NX_MAVEN_CLI_OPTS='--batch-mode'
nx test my-app

# Windows (CMD) - use offline mode
set NX_MAVEN_CLI_OPTS=--offline
nx build my-app

Common options:

  • --no-transfer-progress - Disable download progress output (useful in CI)
  • --batch-mode - Run in non-interactive mode
  • --offline - Work offline (use cached dependencies only)
  • -Dmaven.plugin.validation=VERBOSE - Enable verbose plugin validation

Using a .env file

Create a .env file in your workspace root to persist environment variables across sessions:

# .env file example
NX_MAVEN_CLI=mvnd
NX_MAVEN_CLI_OPTS=--no-transfer-progress --batch-mode

Note: The .env file is automatically loaded by Nx. Variables defined here will be available to all nx-maven commands.

9. Visualizing the project graph

Nx provides a powerful project graph visualization to understand dependencies between your Maven projects:

nx graph

This opens an interactive view showing:

  • Project dependencies - How your applications and libraries depend on each other
  • Build order - Understanding which projects need to be built first
  • Impact analysis - See what projects are affected by changes

Useful graph commands:

# View the full project graph
nx graph

# Show what's affected by changes
nx graph --affected

# Focus on a specific project and its dependencies
nx graph --focus=my-app

# Show only projects that depend on a specific project
nx graph --exclude=*,!tag:my-tag

How nx-maven builds the graph:

  • Maven dependencies - Extracted from pom.xml files (<dependencies> sections)
  • Profile dependencies - Dependencies defined within Maven profiles (<profiles><dependencies>)
  • Plugin dependencies - Dependencies used by Maven plugins (<build><plugins><dependencies>). Note: Plugin dependencies can sometimes create cyclic dependency issues in the graph
  • Parent projects - Child projects depend on their parent (<parent> section)
  • Aggregator projects - Optional linking based on <modules> (controlled by skipAggregatorProjectLinking)

Limitations:

  • Profile dependencies are always included in the graph, regardless of whether the profile is active. This ensures the dependency graph remains consistent but may show dependencies that aren't used in your current build configuration.

Skipping projects:

You can exclude certain projects from the graph by setting skipProjectWithoutProjectJson: true in your plugin configuration. This will skip any Maven projects that don't have a project.json file, which is useful for ignoring Maven modules that aren't managed by Nx.

This integration allows Nx to:

  • Run only affected tests when you make changes
  • Build projects in the correct order
  • Cache and distribute builds efficiently

10. Understanding parent projects vs aggregator projects

Why separate them? In nx-maven, keeping parent projects (configuration) separate from aggregator projects (module lists) improves Nx graph performance. Parent projects stay stable, aggregators only change when adding/removing projects.

Parent Project (--parentProject)

What it does: Child projects inherit configuration and dependency management.

Contains:

  • Dependency versions (<dependencyManagement>)
  • Plugin configurations
  • Java version and properties
  • Framework configurations (Spring Boot, Quarkus, Micronaut)

Example pom.xml:

<parent>
  <groupId>com.example</groupId>
  <artifactId>my-parent</artifactId>
  <version>0.0.1-SNAPSHOT</version>
</parent>

Aggregator Project (--aggregatorProject)

What it does: Lists submodules for coordinated Maven builds.

Contains:

  • Only <modules> declarations
  • No configuration or dependency management (use parent projects for that)

Example pom.xml:

<modules>
  <module>my-app</module>
  <module>my-lib</module>
</modules>

Comparison

Aspect Parent Project Aggregator Project
Purpose Configuration inheritance Build coordination
Direction Bottom-up (child → parent) Top-down (aggregator → modules)
Changes when Configuration updates Projects added/removed

Patterns

1. Default (root as parent and aggregator):

# Generate applications and libraries directly
# They inherit from root pom.xml and are listed there as modules
nx generate @jnxplus/nx-maven:application my-app --framework spring-boot
nx generate @jnxplus/nx-maven:library my-lib --framework spring-boot

All projects inherit configuration from and are aggregated by the root pom.xml.

2. Separate parent and aggregator (recommended for advanced performance):

# Create parent for configuration
nx generate @jnxplus/nx-maven:parent-project shared-config --javaVersion 17

# Create aggregator (modules only, no config)
nx generate @jnxplus/nx-maven:parent-project apps-aggregator --javaVersion none --dependencyManagement none

# Projects inherit from parent, listed in aggregator
nx generate @jnxplus/nx-maven:application app1 --parentProject shared-config --aggregatorProject apps-aggregator

Tip: When using this pattern, enable skipAggregatorProjectLinking: true in your nx.json plugin options to optimize Nx graph performance since aggregators only contain module lists.

11. Project tagging

All projects generated by nx-maven are automatically tagged with nx-maven. This allows you to:

Target Maven projects specifically:

# Run tests only on Maven projects
nx run-many -t test --projects=tag:nx-maven

# Build all Maven projects
nx run-many -t build --projects=tag:nx-maven

# Lint only Maven projects
nx run-many -t lint --projects=tag:nx-maven

Filter in the project graph:

# Show only Maven projects in the graph
nx graph --projects=tag:nx-maven

Custom tags:

You can add additional tags when generating projects using the --tags option:

# Add custom tags
nx generate @jnxplus/nx-maven:application my-app --tags=backend,api

# Projects will have both auto and custom tags: ['nx-maven', 'backend', 'api']

12. Version management

nx-maven handles both static and property-based versions from pom.xml files.

Static versions

<version>0.0.1-SNAPSHOT</version>

Static versions are used directly for dependency resolution and project graph construction.

Property-based versions

nx-maven supports Maven's CI-friendly versions using properties like ${revision}, ${sha1}, or ${changelist}:

<version>${revision}</version>

<properties>
  <revision>1.0.0-SNAPSHOT</revision>
</properties>

Version resolution process:

When nx-maven encounters a property-based version, it resolves it in this order:

  1. Project properties - Check <properties> in the current project's pom.xml
  2. Parent properties - Recursively check parent project properties
  3. Maven evaluation - As a fallback, use mvn help:evaluate (with performance warning)

Example with CI-friendly versions:

<!-- Parent pom.xml -->
<groupId>com.example</groupId>
<artifactId>parent</artifactId>
<version>${revision}</version>

<properties>
  <revision>1.0.0-SNAPSHOT</revision>
</properties>

<!-- Child pom.xml -->
<parent>
  <groupId>com.example</groupId>
  <artifactId>parent</artifactId>
  <version>${revision}</version>
</parent>
<!-- Child inherits revision property from parent -->

Limitations:

  • nx-maven resolves versions statically when building the project graph, not at runtime. If you override versions at build time (e.g., mvn clean install -Drevision=1.2.3), the graph will still use the version defined in <properties>.

Note: If nx-maven cannot resolve a version using properties (e.g., ${project.parent.version}), it will fall back to mvn help:evaluate, which is slower. If you encounter performance issues, please open an issue.

13. Other generators

Preset

The preset generator is used when creating a new Nx workspace with Maven support from scratch:

npx create-nx-workspace@latest my-workspace --preset=@jnxplus/nx-maven

This combines workspace creation and Maven initialization in one step.

Wrapper

Update or add the Maven wrapper to your workspace:

nx generate @jnxplus/nx-maven:wrapper

Options:

  • --skipGitignore - Don't add Maven Wrapper to .gitignore (default: false)
  • --skipFormat - Skip formatting files (default: false)

Use this generator to:

  • Update to the latest Maven wrapper version
  • Add the wrapper if it was skipped during init (--skipWrapper)
  • Restore the wrapper if it was accidentally deleted

License

MIT © 2021-2025 Khalil LAGRIDA