Skip to main content

Java Dependency Analyzer is a tool that inspects dependencies.

Project description

Java Dependency Analyzer 1.5.0

A Python CLI tool that inspects Java dependency hierarchies in Maven and Gradle projects and reports known vulnerabilities.

Prerequisites

Installation

Via pip (recommended)

Install directly from PyPI:

pip install java-dependency-analyzer

From source

Clone the repository and install all dependencies using Poetry:

git clone <repository-url>
cd java-dependency-analyzer
poetry install

Usage

jda [--version] <COMMAND> [OPTIONS] [FILE]

COMMAND is one of gradle, maven, or sbom.

Global options

Option Description
--version Print the installed version and exit.

gradle

jda gradle [OPTIONS] [FILE]

FILE is the path to a build.gradle or build.gradle.kts file. Omit FILE when supplying --dependencies.

Gradle-only options

Option Short Default Description
--module (none) Gradle module name. When supplied, the dependency task becomes <module>:dependencies. Can only be used with --project.

maven

jda maven [OPTIONS] [FILE]

FILE is the path to a pom.xml file. Omit FILE when supplying --dependencies.

sbom

jda sbom [OPTIONS] FILE

FILE is the path to an SBOM JSON file. Supported standards: SPDX 2.3 and CycloneDX 1.6.

sbom-only options

Option Short Required Default Description
--standard -s No cyclonedx SBOM standard of the input file: spdx or cyclonedx (case-insensitive).

Options (gradle / maven subcommands)

Option Short Default Description
--project -p Root directory of the project to analyse. When supplied, the dependency tree is generated automatically and FILE / --dependencies must not be used.
--java-home (system JAVA_HOME) Directory to use as JAVA_HOME. Can only be used with --project.
--use-wrapper false Use the project wrapper script (gradlew/mvnw) instead of the system build tool. Can only be used with --project.
--wrapper (none) Custom wrapper script name to use instead of the default (gradlew/gradlew.bat for Gradle, mvnw/mvnw.cmd for Maven). Can only be used with --use-wrapper.
--dependencies -d Path to a pre-resolved dependency tree text file (see below). When supplied, parsing and transitive resolution are skipped.
--output-format -f all Report format: json, html, or all (both).
--output-dir -o ./reports Directory to write the report file(s) into.
--no-transitive false Skip transitive dependency resolution; analyse direct dependencies only.
--verbose -v false Print progress messages to the console.
--rebuild-cache false Delete the vulnerability cache before scanning.
--cache-ttl 7 Cache TTL in days. Set to 0 to disable caching.

Options (sbom subcommand)

Option Short Default Description
--standard -s cyclonedx SBOM standard of the input file: spdx or cyclonedx.
--output-format -f all Report format: json, html, or all (both).
--output-dir -o ./reports Directory to write the report file(s) into.
--no-transitive false Skip transitive dependency resolution; analyse direct dependencies only.
--verbose -v false Print progress messages to the console.
--rebuild-cache false Delete the vulnerability cache before scanning.
--cache-ttl 7 Cache TTL in days. Set to 0 to disable caching.

Exit Codes

Code Meaning
0 Scan completed successfully; no vulnerabilities found.
10 Scan completed successfully; at least one vulnerability was detected.

Analysing a project directly (--project)

When a Gradle or Maven project is available locally, pass its root directory to --project and jda will generate the dependency tree automatically before scanning:

# Gradle project using the system gradle
jda gradle --project /path/to/my-project

# Gradle multi-module project, analyse the :api module
jda gradle --project /path/to/my-project --module api

# Maven project using the project wrapper, with a custom JAVA_HOME
jda maven --project /path/to/my-project --use-wrapper --java-home /usr/lib/jvm/java-21

# Gradle project using a custom wrapper script name
jda gradle --project /path/to/my-project --use-wrapper --wrapper gradlew-local
  • --java-home overrides the JAVA_HOME environment variable for the invocation. If neither is set, the command fails with a clear error.
  • --use-wrapper invokes gradlew/gradlew.bat (Gradle) or mvnw/mvnw.cmd (Maven) from the project root. A UsageError is raised when the wrapper script is absent.
  • --wrapper overrides the default wrapper script name used by --use-wrapper. Can only be used with --use-wrapper.
  • --module (Gradle only) specifies a sub-module; the dependency task becomes <module>:dependencies. Can only be used with --project.
  • --project is mutually exclusive with both FILE and --dependencies.

Pre-resolved dependency trees (--dependencies)

When a Gradle or Maven project already has a dependency tree available (e.g. from CI), you can pass it directly to skip the parser and transitive resolver:

  • Gradle: generate with gradle dependencies --configuration runtimeClasspath > gradle.txt
  • Maven: generate with mvn dependency:tree -Dscope=runtime > maven.txt

The report will reflect the exact tree from the file, including all transitive dependencies.

Generating SBOM files

Use one of the approaches below to produce an SBOM JSON file that jda sbom can consume.

CycloneDX 1.6

Gradle — add the CycloneDX Gradle plugin to build.gradle:

plugins {
    id 'org.cyclonedx.bom' version '3.2.4'
}

Or for Kotlin DSL (build.gradle.kts):

plugins {
    id("org.cyclonedx.bom") version "3.2.4"
}

Then run:

gradle cyclonedxBom

Output: build/reports/bom.json

Maven — run the CycloneDX Maven plugin without modifying pom.xml:

mvn org.cyclonedx:cyclonedx-maven-plugin:makeAggregateBom

Output: target/bom.json

SPDX 2.3

JDA expects a SPDX JSON document where each package entry in the packages array has an externalRefs entry with referenceType: "purl" and a referenceLocator in the form pkg:maven/{groupId}/{artifactId}@{version}.

Gradle and Maven — use syft:

# Gradle project
syft /path/to/gradle-project -o spdx-json=sbom.spdx.json

# Maven project
syft /path/to/maven-project -o spdx-json=sbom.spdx.json

Examples

Analyse a Maven POM and produce both JSON and HTML reports in the current directory:

jda maven pom.xml

Analyse a Gradle build file and write only an HTML report to ./reports/:

jda gradle build.gradle -f html -o reports/

Analyse direct dependencies only, with verbose output:

jda gradle build.gradle.kts --no-transitive -v

Scan using a pre-resolved Gradle dependency tree (skips transitive resolution):

jda gradle --dependencies runtime.txt -f json -o reports/

Scan using a pre-resolved Maven dependency tree (skips transitive resolution):

jda maven --dependencies maven.txt -f json -o reports/

Analyse a Gradle project directly (auto-generates the dependency tree):

jda gradle --project /path/to/my-gradle-project --use-wrapper

Analyse a Maven project directly with a custom JAVA_HOME:

jda maven --project /path/to/my-maven-project --java-home /usr/lib/jvm/java-21

Analyse a specific Gradle module using a custom wrapper script:

jda gradle --project /path/to/my-gradle-project --module api --use-wrapper --wrapper gradlew-local

Scan a CycloneDX SBOM file and produce both JSON and HTML reports:

jda sbom --standard cyclonedx bom.json

Scan an SPDX SBOM file and write an HTML report to a custom directory:

jda sbom --standard spdx sbom.spdx.json -f html -o reports/

Configuration

Environment Variable Required Default Description
GITHUB_TOKEN No (none) A GitHub personal access token. When set, the GhsaScanner uses it to authenticate requests to the GitHub Advisory Database REST API, which significantly increases the rate limit (from ~60 unauthenticated requests/hour to 5 000 authenticated requests/hour). Without it, scans with many dependencies may trigger HTTP 403/429 responses and fall back to the OSV.dev API.
GHSA_API_URL No https://api.github.com/advisories Override the GitHub Advisory Database REST API endpoint used by GhsaScanner. Useful for proxies or air-gapped mirrors.
OSV_QUERY_URL No https://api.osv.dev/v1/query Override the OSV.dev single-query endpoint used by OsvScanner.
OSV_VULN_URL No https://osv.dev/vulnerability/ Override the OSV.dev vulnerability detail base URL embedded in reports.
MAVEN_CENTRAL_URL No https://repo1.maven.org/maven2 Override the Maven Central repository URL used by TransitiveResolver to fetch POM files.
JDA_CONFIG_DIR No (none) Directory used to store and load a custom logging.ini. On first run, the bundled logging.ini is seeded into this directory. If not set, the bundled config is loaded directly from the package.

Set it in your shell or in a .env file in the working directory before running jda:

# shell
export GITHUB_TOKEN=ghp_yourTokenHere

# or in .env
GITHUB_TOKEN=ghp_yourTokenHere

Logging

The tool writes logs to java_dependency_analyzer.log in the current working directory and prints progress messages to the console via Rich.

A logging.ini is bundled inside the package and loaded automatically — no manual setup is required after installation.

Custom logging configuration

To override the default logging settings, set the JDA_CONFIG_DIR environment variable to a directory path. On first run, jda seeds the bundled logging.ini into that directory; edit the copy there to customise log levels, file paths, or handlers:

# shell
export JDA_CONFIG_DIR=/path/to/my-config

# or in .env
JDA_CONFIG_DIR=/path/to/my-config

Architecture

graph TD
    CLI["jda CLI (cli.py)"] --> Parser["DependencyParser (ABC)"]
    Parser --> MavenParser
    Parser --> GradleParser
    Parser --> MavenDepTreeParser
    Parser --> GradleDepTreeParser
    Parser --> SbomParser
    CLI --> Resolver["TransitiveResolver<br/>(Maven Central)"]
    CLI --> Scanner["VulnerabilityScanner (ABC)"]
    Scanner --> OsvScanner["OsvScanner<br/>(OSV.dev API)"]
    Scanner --> GhsaScanner["GhsaScanner<br/>(GitHub Advisory DB)"]
    OsvScanner --> Cache["VulnerabilityCache<br/>(SQLite)"]
    GhsaScanner --> Cache
    CLI --> Reporter["Reporter (ABC)"]
    Reporter --> JsonReporter
    Reporter --> HtmlReporter
    MavenParser --> Dependency["Dependency / Vulnerability<br/>Dataclasses"]
    GradleParser --> Dependency
    MavenDepTreeParser --> Dependency
    GradleDepTreeParser --> Dependency
    SbomParser --> Dependency
    Resolver --> Dependency
    OsvScanner --> Dependency
    GhsaScanner --> Dependency
    JsonReporter --> ScanResult["ScanResult"]
    HtmlReporter --> ScanResult
    Dependency --> ScanResult

Components

Component Location Responsibility
CLI java_dependency_analyzer/cli.py Entry point (gradle / maven / sbom subcommands); orchestrates parsing, resolving, scanning, and reporting.
MavenParser parsers/maven_parser.py Parses pom.xml, resolves ${property} placeholders, filters by runtime scope.
GradleParser parsers/gradle_parser.py Parses Groovy DSL (build.gradle) and Kotlin DSL (build.gradle.kts) files.
MavenDepTreeParser parsers/maven_dep_tree_parser.py Parses mvn dependency:tree text output into a full dependency tree.
GradleDepTreeParser parsers/gradle_dep_tree_parser.py Parses gradle dependencies text output into a full dependency tree.
SbomParser parsers/sbom_parser.py Parses SBOM JSON files in SPDX 2.3 or CycloneDX 1.6 format; extracts Maven dependencies via package URLs (pkg:maven/…).
TransitiveResolver resolvers/transitive.py Fetches transitive dependencies by downloading POM files from Maven Central.
OsvScanner scanners/osv_scanner.py Queries the OSV.dev batch API for known CVEs.
GhsaScanner scanners/ghsa_scanner.py Queries the GitHub Advisory Database REST API for security advisories; automatically falls back to OSV when rate-limited (HTTP 403/429).
VulnerabilityCache cache/vulnerability_cache.py SQLite-backed cache for raw vulnerability API payloads with configurable TTL.
DatabaseManager cache/db.py Manages SQLite connection lifecycle and schema initialisation.
xml_helpers util/xml_helpers.py Shared POM XML utilities: POM_NS constant and detect_pom_namespace() for handling namespace-qualified and namespace-free POM documents.
JsonReporter reporters/json_reporter.py Writes a ScanResult to a JSON file.
HtmlReporter reporters/html_reporter.py Renders a ScanResult to a styled HTML report via a Jinja2 template.

Development Setup

Install all dependencies (including dev tools):

poetry install

Running Tests

Run the full test suite with coverage and generate an HTML report:

poetry run pytest --cov=java_dependency_analyzer tests --cov-report html

Code Quality

Format and lint the source code (linter must score 10/10):

poetry run black java_dependency_analyzer
poetry run pylint java_dependency_analyzer

Publishing to PyPI

Prerequisites

  • A PyPI account with an API token.

Configure the token

poetry config pypi-token.pypi <your-token>

Build and publish

poetry publish --build

This builds the source distribution and wheel, then uploads them to PyPI in one step.

Note: PyPI releases are immutable. Once a version is published, it cannot be overwritten.
To fix a mistake, yank the release via the PyPI web UI and publish a new version.

Changelog

Author

Ron Webb <ron@ronella.xyz>

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

java_dependency_analyzer-1.5.0.tar.gz (39.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

java_dependency_analyzer-1.5.0-py3-none-any.whl (55.0 kB view details)

Uploaded Python 3

File details

Details for the file java_dependency_analyzer-1.5.0.tar.gz.

File metadata

  • Download URL: java_dependency_analyzer-1.5.0.tar.gz
  • Upload date:
  • Size: 39.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/2.3.4 CPython/3.14.4 Windows/11

File hashes

Hashes for java_dependency_analyzer-1.5.0.tar.gz
Algorithm Hash digest
SHA256 295f104b0c8f87bc54d15653724422d3b4ba44780cf0f24f15b2b519f60d900d
MD5 1429daa721d01e4a0595e77cdbf49e44
BLAKE2b-256 d7e4c344013ba9dc1498abbb9f0ce7c0372ae65092d4ec2f6eb4386d16c67960

See more details on using hashes here.

File details

Details for the file java_dependency_analyzer-1.5.0-py3-none-any.whl.

File metadata

File hashes

Hashes for java_dependency_analyzer-1.5.0-py3-none-any.whl
Algorithm Hash digest
SHA256 d12022514a867aeaff0eb0ebb7e2b64df4d47e0a7fae868e4c84ea15c4871555
MD5 5c4fbe7e77e69986a844fcd5b309bebb
BLAKE2b-256 3452227653b9d2bd59f8f226425af3aa105920fd24b9759c33c918001ff43563

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page