jvmreach

package
v0.16.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 7, 2026 License: Apache-2.0 Imports: 18 Imported by: 0

Documentation

Overview

Package jvmreach implements a Tier-3 (package-level) reachability analyzer for JVM-ecosystem packages (Maven, Gradle, SBT). It walks application source files rooted at a JVM project, scans every reachable .java / .kt / .kts / .scala / .groovy file for top-of-file import statements, maps the imported FQN prefixes to Maven artifact coordinates (`groupId:artifactId`), and reports each registry vulnerability as Reachable / Unreachable / Unknown depending on whether the artifact appears in the import set (expanded transitively through the dep graph).

Tier-3 caveat: "unreachable" here means "the application source does not import this artifact, neither directly nor indirectly through app code". It does NOT mean "the vulnerability cannot be triggered" — JVM apps use reflection, ServiceLoader, classpath scanning, Spring component scanning, and OSGi/JPMS dynamic loading, all of which are invisible to a static scanner. See docs/REACHABILITY.md for the full set of caveats.

The runner reads source in-process. The Runner interface is preserved so unit tests can inject a fake runner for deterministic behavior.

Index

Constants

View Source
const Name = "jvmreach"

Name is the analyzer's stable identifier (used in selectors and output).

Variables

This section is empty.

Functions

This section is empty.

Types

type Analyzer

type Analyzer struct {
	Runner       Runner
	Logger       *zap.Logger
	CacheDir     string
	CacheTTL     time.Duration
	DisableCache bool
}

Analyzer is a Tier-3 (package-level) reachability analyzer for JVM-ecosystem packages. It groups Maven artifacts in the input graph by project root, runs the configured Runner once per project, and annotates each registry vulnerability on JVM packages with a Reachability result.

Tier-3 caveat: "unreachable" means "the application source does not import this artifact, neither directly nor through any dep-graph edge from a directly-imported neighbor". It does NOT mean "the vulnerability cannot be triggered" — reflection, ServiceLoader, Spring component scanning, OSGi, and JPMS dynamic loading are all invisible to a static scanner. See docs/REACHABILITY.md for the full caveat list.

func (Analyzer) Analyze

func (Analyzer) Applicable

func (a Analyzer) Applicable(_ context.Context, req model.AnalyzeRequest) (bool, error)

func (Analyzer) Descriptor

func (a Analyzer) Descriptor() model.AnalyzerDescriptor

Descriptor returns the registration metadata for the jvmreach analyzer.

func (Analyzer) Ready

type Runner

type Runner interface {
	// Name returns a stable identifier (e.g. "library") used in
	// telemetry and Reason fields.
	Name() string
	// Version returns the runner schema version. The result cache
	// folds it into its key so scanner upgrades invalidate prior
	// entries automatically.
	Version() string
	// Run walks projectDir and returns the imported-artifact set.
	// projectDir must look like a JVM project root (pom.xml,
	// build.gradle(.kts), build.sbt, or settings.gradle(.kts)).
	Run(ctx context.Context, projectDir string) (RunnerResult, error)
}

Runner walks a JVM project rooted at projectDir and returns the set of Maven artifact coordinates (`groupId:artifactId`) imported anywhere in its reachable source tree. Implementations must NEVER panic and should map missing inputs, parse errors, and other recoverable conditions to a (RunnerResult, error) pair where the error is descriptive but does not abort the pipeline.

func NewRunner

func NewRunner(logger *zap.Logger) Runner

NewRunner returns the in-process Runner — a line-oriented scanner that walks the project's JVM source tree and records every imported FQN, resolving each through the prefix map to a Maven coordinate set.

type RunnerResult

type RunnerResult struct {
	// ImportedArtifacts is the set of Maven coordinates ("group:artifact",
	// lowercase) that the prefix map resolved from source-level
	// imports. The analyzer matches graph packages against this set
	// before walking transitive deps.
	ImportedArtifacts map[string]struct{}
	// RawImports is the set of source-level fully qualified imports.
	// The analyzer uses it to resolve references between local modules.
	RawImports map[string]struct{}
	// SourceFiles is the count of project source files visited
	// (.java / .kt / .kts / .scala / .groovy).
	SourceFiles int
	// SkippedDirs lists directory names skipped during the walk
	// (target/, build/, .gradle/, etc.) for debug logging.
	SkippedDirs []string
	// DynamicImportsDetected is true when the runner observed
	// reflection-based class loading the static scanner cannot
	// follow: Class.forName(name) on a variable, ClassLoader.loadClass,
	// ServiceLoader.load, ResourceBundle.getBundle on a variable. When
	// true, an "unreachable" verdict is necessarily incomplete and the
	// per-vuln Reachability.DynamicImportsDetected flag is set.
	DynamicImportsDetected bool
}

RunnerResult is the parsed output of one runner pass over a project.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL