maven
Last updated July 30, 2026View source (v0.21.1)
Bomly uses this chain when it finds maven evidence.
| Property | Value |
|---|---|
| Package manager | maven |
| Ecosystem | maven |
| Detector chain | maven-detector, syft-detector |
| Evidence patterns | pom.xml, *pom.xml |
| Ignored directories | target |
| Ignored directory markers | - |
| Multi-module resolution | Yes |
| Install-first support | Yes |
| Remediation hints | direct-bump1, transitive-override2 |
| Native command hints | mvn, syft for bomly-lite |
How maven resolves
maven-detector is a build-tool primary chain — there is no committed-lockfile fallback. Maven projects don't ship lockfiles in general use, so Bomly drives Maven's own resolver to produce the graph.
| Step | Command | Working dir |
|---|---|---|
| Resolve graph | mvn dependency:tree -DoutputType=tgf (uses ./mvnw wrapper if present) | every directory containing a pom.xml |
The TGF (Trivial Graph Format) output is parsed into a full transitive graph with Maven scopes (compile, runtime, test, provided, system) preserved as edge attributes.
Network behavior
⚠️ mvn dependency:tree may download artifacts during normal scan, before --enrich:
- If a referenced artifact (including parent POMs, BOM imports, plugins) is not in your local repository (
~/.m2/repository), Maven will fetch it from Maven Central (or whatever repositories yoursettings.xmldeclares). - Build-tool execution is Maven's, not Bomly's. The same network calls happen when you run
mvn compilelocally.
To keep the scan fully offline:
- Pre-warm
~/.m2/repositoryby runningmvn dependency:go-offlineonce. - Or pass
-DskipResolutionCheckand accept that uncached transitives will be missing.
Prerequisites
mvn(or./mvnwMaven Wrapper) onPATH. The detector cannot resolve without invoking Maven.- A valid
pom.xmlat every module root. Multi-module reactors are supported; eachpom.xmlis its own subproject. - Authentication for private repositories: configure
~/.m2/settings.xmlas usual. Bomly does not authenticate to repositories itself.
--install-first
maven supports --install-first. When passed, Bomly runs mvn dependency:resolve (using ./mvnw if present) before resolving the graph. This warms ~/.m2/repository so the subsequent mvn dependency:tree runs offline.
⚠️ --install-first downloads artifacts from Maven Central (or whatever repositories your settings.xml declares). Use it on a clean checkout when the local repository is cold.
bomly scan --install-first
Customizing the install command
Append flags to mvn dependency:resolve with repeatable --install-arg. Requires --detectors maven-detector.
# Activate a specific Maven profile and point at a settings file
bomly scan --install-first --detectors maven-detector \
--install-arg -Pproduction \
--install-arg --settings --install-arg ./ci-settings.xml
Examples
Fix a direct vulnerability
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.17.1</version>
</dependency>
Re-scan.
Pin a transitive vulnerability
Use <dependencyManagement> to override the version a transitive dep resolves to:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.17.1</version>
</dependency>
</dependencies>
</dependencyManagement>
Re-scan.
Reachability (experimental)
Experimental. Reachability is opt-in via
--analyze. The feature is stable in shape but may evolve; ecosystem coverage is expanding.
For Maven packages, the analyzer is jvmreach at Tier-3 (package). It walks .java, .kt, .kts, .scala, .groovy source files under the project root, parses top-of-file import statements, and maps fully-qualified-name prefixes to Maven coordinates via a curated longest-prefix map. See REACHABILITY.md.
For multi-module reactors, jvmreach reads parent <modules> declarations recursively and follows source namespace imports between consumed sibling modules before attributing external artifacts.
If a missing prefix produces a false-negative for a direct import, add the mapping to internal/analyzers/jvmreach/prefixmap.go (one-line PR).
Limitations
- System-scoped dependencies (
<scope>system</scope>) are recorded but not classified by ecosystem — Bomly cannot follow<systemPath>to a Maven coordinate. - Classifier-only differences are collapsed to a single graph node; if two artifacts differ only by classifier (e.g.
linux-x86_64vs.macos-aarch64), reachability annotates them identically. - Annotation processors that generate code at build time are invisible to source-based reachability.
mvnis required. There is no offline-only path for Maven graph resolution.