feat(langmgr): scaffold Java/JVM language manager (foundation)#1594
feat(langmgr): scaffold Java/JVM language manager (foundation)#1594omercnet wants to merge 2 commits into
Conversation
First step of the Java patching roadmap. Wires Trivy's four Java/JVM language types (jar, pom, gradle, sbt) through the report parser and registers a single javaManager in pkg/langmgr that handles all four (they all map to packageurl.TypeMaven upstream). InstallUpdates is intentionally a no-op scaffold: it returns the unchanged image state and reports every Java update as a failed package so the orchestrator routes them through --ignore-errors handling. The full strategy (download patched JARs from a Maven repository and replace each copy in the target image) is implemented in follow-up PRs tracked in the Java patching roadmap issue. Changes: - pkg/utils: register JavaJar, JavaPom, JavaGradle, JavaSbt type constants - pkg/report/trivy.go: forward Java entries into LangUpdates instead of dropping them at the type filter - pkg/langmgr/java.go: javaManager scaffold with isJavaUpdate / filterJavaUpdates helpers - pkg/langmgr/langmgr.go: register javaManager in GetLanguageManagers, deduplicated across all four Java types - regression tests: parser forwards each of the four types; manager is registered exactly once across types; non-Java updates are ignored; nil-manifest is safe No production behavior change for non-Java users. Java users gain a clear log message instead of silent drop and can use --ignore-errors to continue patching the rest of the image. Signed-off-by: Omer <omer@descope.com>
There was a problem hiding this comment.
Pull request overview
This PR lays the groundwork for Java/JVM library patching by plumbing Trivy’s Java language result types (jar, pom, gradle, sbt) into Copa’s vulnerability manifest and registering a scaffold javaManager so Java findings are no longer silently dropped.
Changes:
- Add Java language type constants and allow Trivy parsing to forward those results into
LangUpdates. - Register a new
javaManager(single manager for all four Java types) inGetLanguageManagers. - Add unit tests to validate parser forwarding and manager registration/behavior.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| pkg/utils/utils.go | Adds Java language type constants used across parsing/manager selection. |
| pkg/report/trivy.go | Extends Trivy language-type filter to include Java types. |
| pkg/report/trivy_test.go | Adds coverage to ensure Java language findings are forwarded into LangUpdates. |
| pkg/langmgr/java.go | Introduces scaffold javaManager and helper functions for identifying/filtering Java updates. |
| pkg/langmgr/langmgr.go | Registers javaManager once across all Java types. |
| pkg/langmgr/langmgr_test.go | Adds tests for java manager registration + scaffold failure reporting behavior. |
| @@ -438,7 +438,8 @@ func (t *TrivyParser) ParseWithLibraryPatchLevel(file, libraryPatchLevel string) | |||
| // Process Language packages | |||
| if r.Class == utils.LangPackages { | |||
| // Check if this is a Python, Node.js, or Go related target | |||
| } | ||
|
|
||
| // isJavaUpdate returns true when the package type is one of Trivy's Java | ||
| // language types. Used by both the manager and the report parser. |
| // InstallUpdates is the LangManager entry point. The foundation scaffold logs | ||
| // each affected coordinate, returns the unchanged state, and reports the Java | ||
| // updates as failed packages so the caller can decide whether to hard-fail or | ||
| // continue under --ignore-errors. | ||
| func (jm *javaManager) InstallUpdates( | ||
| _ context.Context, | ||
| currentState *llb.State, | ||
| manifest *unversioned.UpdateManifest, | ||
| _ bool, | ||
| ) (*llb.State, []string, error) { | ||
| if manifest == nil || len(manifest.LangUpdates) == 0 { | ||
| return currentState, nil, nil | ||
| } | ||
|
|
||
| javaUpdates := filterJavaUpdates(manifest.LangUpdates) | ||
| if len(javaUpdates) == 0 { | ||
| return currentState, nil, nil | ||
| } | ||
|
|
||
| log.Warnf("Java/JVM library patching is not yet implemented. %d update(s) skipped.", len(javaUpdates)) | ||
| failed := make([]string, 0, len(javaUpdates)) | ||
| for _, u := range javaUpdates { | ||
| log.Debugf(" Java skipped: %s (installed=%s, fixed=%s, type=%s, path=%s)", | ||
| u.Name, u.InstalledVersion, u.FixedVersion, u.Type, u.PkgPath) | ||
| failed = append(failed, u.Name) | ||
| } | ||
| return currentState, failed, nil |
| // each affected coordinate, returns the unchanged state, and reports the Java | ||
| // updates as failed packages so the caller can decide whether to hard-fail or | ||
| // continue under --ignore-errors. | ||
| func (jm *javaManager) InstallUpdates( |
There was a problem hiding this comment.
agree with the copilot comment regarding ignore errors. Also, we should exit non-zero / make sure no -patched image is created when no updates were applied
| PkgName: tc.pkgName, | ||
| InstalledVersion: "1.0.0", | ||
| FixedVersion: "1.0.1", | ||
| PkgPath: "/usr/share/app/lib/" + strings.ReplaceAll(tc.pkgName, ":", "-") + "-1.0.0.jar", |
There was a problem hiding this comment.
where are we getting this path pattern from?
|
@omercnet thanks for putting this up! I had a few comments and also agree with the comments put up by Copilot |
First step of the Java patching roadmap tracked in #1593. Wires Trivy's four Java/JVM language types (
jar,pom,gradle,sbt) through the report parser and registers a singlejavaManagerinpkg/langmgrthat handles all four (they all map topackageurl.TypeMavenupstream).Why
copacurrently drops every Java entry atpkg/report/trivy.go's type filter. The five accepted lang types arepython-pkg,node-pkg,gomod,gobinary,dotnet-core. Java users get zero entries inLangUpdateseven when Trivy reports hundreds of fixable Java CVEs. This PR establishes the surface area without changing production behavior for non-Java users.What changes
pkg/utils/utils.goJavaJar,JavaPom,JavaGradle,JavaSbtconstantspkg/report/trivy.goLangUpdatesinstead of dropping them at the type filterpkg/langmgr/java.gojavaManagerscaffold withisJavaUpdate/filterJavaUpdateshelperspkg/langmgr/langmgr.gojavaManagerinGetLanguageManagers, deduplicated across all four Java types (same pattern as the existing Go manager handlinggomod+gobinary)pkg/langmgr/langmgr_test.gojavaManageris registered exactly once across types; non-Java updates are ignored; nil-manifest is safe; failure list contains every Java coordinatepkg/report/trivy_test.goType,Name,InstalledVersion,FixedVersionpreservedScaffold semantics (intentional)
InstallUpdatesis a no-op: it returns the unchanged image state and reports every Java update as a failed package. This routes Java users through--ignore-errorshandling instead of silently dropping their vulns. Subsequent PRs in #1593 implement the Maven-Central download + JAR-swap strategy.What this PR is not
Verification
gofmt -l pkg/: cleango build ./...: cleango vet ./...: cleango test ./pkg/langmgr/... ./pkg/report/...: passgolangci-lint run --new-from-rev=upstream/main: 0 issuesDiff summary