Tech Blog

Self-Contained Project Configuration: Running Maven / Node / Java on Windows Without PATH Dependencies

by Tech Writer
Windows Maven Node.js Spring Boot

Introduction

“When a new member joins, the first step is always aligning Java, Node.js, and Maven versions.”

Even for solo development, the same problem occurs when you change PCs or reset your environment.

This project adopted a configuration that confines Maven, Node, and npm inside the project folder,
without depending on the system PATH.


Configuration Overview

dvd-rental-admin/
  mvnw          ← Maven Wrapper (for macOS/Linux)
  mvnw.cmd      ← Maven Wrapper (for Windows)
  node/
    npm         ← npm (for macOS/Linux)
    npm.cmd     ← npm (for Windows)
    npx
    npx.cmd
  package.json  ← npm configuration for frontend build

When running build commands, we use the commands inside the project rather than the system-installed Maven and Node.


Maven Wrapper

mvnw / mvnw.cmd is the Maven Wrapper.
When executed, it automatically downloads and runs the version of Maven specified in .mvn/wrapper/maven-wrapper.properties.

# .mvn/wrapper/maven-wrapper.properties
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.6/apache-maven-3.9.6-bin.zip

Usage

# Uses the project-specified version, not the system Maven
.\mvnw.cmd clean package

# Can build even if the mvn command isn't installed on the system

How to Create

# Generate wrapper in an environment that has an existing Maven
mvn wrapper:wrapper -Dmaven=3.9.6

Confining Node / npm Inside the Project

Installing Node Inside the Project via npm install

By placing Node.js binaries in the node folder, we separate it from the system Node.

// package.json
{
  "engines": {
    "node": ">=22.0.0"
  },
  "scripts": {
    "build:css": "node/npm.cmd run tailwind",
    "build:ts": "node/npx.cmd tsc"
  }
}

Or using frontend-maven-plugin:

<!-- pom.xml -->
<plugin>
    <groupId>com.github.eirslett</groupId>
    <artifactId>frontend-maven-plugin</artifactId>
    <version>1.15.0</version>
    <configuration>
        <installDirectory>node</installDirectory>  <!-- Place in project's node/ -->
        <nodeVersion>v22.0.0</nodeVersion>
    </configuration>
    <executions>
        <execution>
            <id>install-node-and-npm</id>
            <goals><goal>install-node-and-npm</goal></goals>
        </execution>
    </executions>
</plugin>

Running mvn generate-resources installs Node.js into the node/ folder.


Notes on Path Resolution in Windows

The .cmd extension is important in Windows.

# NG: Without extension may not work in Windows PowerShell
.\mvnw clean package

# OK: Explicitly specify .cmd
.\mvnw.cmd clean package
.\node\npm.cmd run build

Also, if the working directory is not the project root, .\mvnw.cmd will fail to resolve.

# NG: When you're in a subdirectory
cd infra/cdk
.\mvnw.cmd package  # ← Error: mvnw.cmd not found

# OK: Return to project root before executing
cd C:\Users\y_104\git\dvd-rental-admin
.\mvnw.cmd package

# Or execute with absolute path
C:\Users\y_104\git\dvd-rental-admin\mvnw.cmd package

VS Code Task Configuration

Defining in VS Code’s .vscode/tasks.json lets you build without opening a terminal.

{
  "version": "2.0.0",
  "tasks": [
    {
      "label": "build-backend",
      "type": "shell",
      "command": ".\\mvnw.cmd",
      "args": ["-DskipTests", "package"],
      "options": {
        "cwd": "${workspaceFolder}"  // ← Explicitly specify workspaceFolder
      },
      "group": "build"
    },
    {
      "label": "build-frontend",
      "type": "shell",
      "command": ".\\node\\npm.cmd",
      "args": ["run", "build"],
      "options": {
        "cwd": "${workspaceFolder}"
      },
      "group": "build"
    }
  ]
}

.gitignore Configuration

We don’t commit the Node and Maven caches inside the project.

# Maven Wrapper download cache
.mvn/wrapper/maven-wrapper.jar  # Exclude JAR (Wrapper auto-downloads it)

# Node binaries (downloaded by frontend-maven-plugin)
node/node_modules/
node/node.exe
node/npm
node/npm.cmd
node/npx
node/npx.cmd

# But track the node/ folder itself (as empty directory)

Team Rollout (Onboarding)

With this configuration, setup in a new environment comes down to these commands:

# 1. Clone the repository
git clone https://github.com/your-org/dvd-rental-admin.git
cd dvd-rental-admin

# 2. Install Node (frontend-maven-plugin auto-downloads)
.\mvnw.cmd generate-resources

# 3. Frontend build
.\node\npm.cmd install
.\node\npm.cmd run build

# 4. Backend build and startup
.\mvnw.cmd spring-boot:run

Java version specification is managed with .sdkmanrc (when using SDKMAN) or .java-version (when using jenv).


Summary

ProblemSolution
System Maven version doesn’t matchUse mvnw / mvnw.cmd
System Node/npm unavailable or wrong versionUse frontend-maven-plugin to download inside project
.\mvnw.cmd doesn’t work on WindowsSet working directory to project root
Complex environment setup for new membersSelf-contained configuration minimizes clone-to-build steps

By achieving the state of “everything needed to build this project is inside this folder,“
you can dramatically reduce trouble from environment differences.


Article Map for This Series

Building a DVD Rental End-User App alongside the Admin App — Vue 3 + Spring Boot Full Architecture and Article Map

Feel free to send a message

Please send a message if you have any technical questions, feedback, or inquiries.