Skip to content

fix: combine SrcDir with sourcepath in FindbugsParser to produce complete file paths#197

Merged
tomasbjerre merged 5 commits into
masterfrom
copilot/fix-findbugsparser-file-path
Mar 7, 2026
Merged

fix: combine SrcDir with sourcepath in FindbugsParser to produce complete file paths#197
tomasbjerre merged 5 commits into
masterfrom
copilot/fix-findbugsparser-file-path

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Mar 7, 2026

FindbugsParser was ignoring <SrcDir> from the <Project> element and using only the raw sourcepath attribute (e.g., com/example/Foo.java), producing package-relative paths that can't be resolved to actual files — especially in multi-module Maven projects.

Changes

  • parseReportOutput(): collects <SrcDir> entries from the <Project> element via streaming parse, passes them to parseBugInstance()
  • parseBugInstance(): delegates filename resolution to new resolveFilePath()
  • resolveFilePath(): prepends the single SrcDir to sourcepath; only applies when there is exactly one SrcDir entry in total and it is a directory (not ending with .java) — falls back to raw sourcepath unchanged when there are zero or multiple SrcDir entries, fully preserving existing behavior

Example

Given:

<Project>
  <SrcDir>/builds/my-project/module-a/src/main/java</SrcDir>
</Project>
<BugInstance type="MS_EXPOSE_REP" ...>
  <SourceLine sourcepath="com/example/Foo.java" start="42" end="42" .../>
</BugInstance>

Before: violation.getFile()com/example/Foo.java
After: violation.getFile()/builds/my-project/module-a/src/main/java/com/example/Foo.java

The absolute path can then be made project-relative via ViolationUtils.relativePath.

Reports with multiple SrcDir entries (e.g. a mix of a source root and individual .java file paths) are unaffected — the raw sourcepath is returned as-is.

Test coverage

  • testThatSrcDirIsCombinedWithSourcepathWhenExactlyOneSrcDir: new test using spotbugs-one-srcdir.xml — a minimal real-format SpotBugs report with exactly one directory SrcDir, asserting the combined path /builds/my-project/module-a/src/main/java/com/example/Foo.java
  • testThatViolationsCanBeParsedFromSpotbugs2: uses the real spotbugs-main.xml report, which has multiple SrcDir entries, confirming the raw sourcepath is preserved unchanged in that case
Original prompt

This section details on the original issue you should resolve

<issue_title>FindbugsParser does not combine SrcDir with sourcepath</issue_title>
<issue_description>## Problem

The FindbugsParser uses only the sourcepath attribute from <SourceLine> elements, without combining it with <SrcDir> from the <Project> element. This produces incorrect (incomplete) file paths in the parsed violations.

Expected behavior

For a SpotBugs XML like:

<Project>
  <SrcDir>/builds/my-project/module-a/src/main/java</SrcDir>
</Project>
<BugInstance type="MS_EXPOSE_REP" ...>
  <SourceLine classname="com.example.Foo"
              sourcepath="com/example/Foo.java"
              start="42" end="42" .../>
</BugInstance>

The violation file path should be resolved to either:

  • Absolute: /builds/my-project/module-a/src/main/java/com/example/Foo.java (which ViolationUtils.relativePath can then make relative)
  • Or project-relative: module-a/src/main/java/com/example/Foo.java

Actual behavior

The violation file path is just com/example/Foo.java (the raw sourcepath attribute), which is relative to the source root, not to the project root.

Source: FindbugsParser.java line 101:

final String filename = getAttribute(xmlr, "sourcepath");

The <SrcDir> element is never read.

Impact

When using violations-command-line with -cc (CodeClimate output) for GitLab Code Quality integration, SpotBugs findings get incorrect file paths. GitLab can not resolve these paths to actual files in the repository, resulting in broken links in the MR code quality widget and diff annotations.

This is especially problematic in multi-module Maven projects where the source path needs to include the module directory (e.g., module-a/src/main/java/com/example/Foo.java).

PMD and Checkstyle are not affected because their XML reports contain absolute file paths in <file name="...">.

Suggested fix

In FindbugsParser.parseReportOutput(), parse <SrcDir> elements from the <Project> section first, then in parseBugInstance(), combine the matching SrcDir with sourcepath:

// During Project parsing:
List<String> srcDirs = new ArrayList<>();
// ... parse <SrcDir> elements ...
// In parseBugInstance, when processing SourceLine:
final String sourcepath = getAttribute(xmlr, "sourcepath");
String filename = sourcepath;
for (String srcDir : srcDirs) {
    String candidate = srcDir + "/" + sourcepath;
    filename = candidate;
    break;
}

Environment

  • violations-command-line: 4.0.2
  • violations-lib: (bundled)
  • SpotBugs Maven Plugin: 4.9.x
  • Multi-module Maven project with spotbugsXml.xml per module
    </issue_description>

Comments on the Issue (you are @copilot in this section)


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

@tomasbjerre
Copy link
Copy Markdown
Owner

tomasbjerre commented Mar 7, 2026

@copilot
Use conventional commits.
Only add test case to violations-lib/src/test/java/se/bjurr/violations/lib/FindbugsTest.java and test using a real report file.

…e paths

Co-authored-by: tomasbjerre <439571+tomasbjerre@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix FindbugsParser to combine SrcDir with sourcepath FindbugsParser: combine SrcDir with sourcepath to produce complete file paths Mar 7, 2026
@tomasbjerre
Copy link
Copy Markdown
Owner

@copilot keep existing functionality if there is several SrcDir and only use SrcDir if there is exactly one.

…ype SrcDir exists

Co-authored-by: tomasbjerre <439571+tomasbjerre@users.noreply.github.com>
Copy link
Copy Markdown
Contributor Author

Copilot AI commented Mar 7, 2026

@copilot
Use conventional commits.
Only add test case to violations-lib/src/test/java/se/bjurr/violations/lib/FindbugsTest.java and test using a real report file.
...

Done in 8ee6760. Removed the synthetic spotbugs-srcdir.xml fixture and the test that used it. The existing testThatViolationsCanBeParsedFromSpotbugs2 now covers the fix using the real spotbugs-main.xml report (which has exactly one directory-type SrcDir). Commit message now follows conventional commits.

@copilot keep existing functionality if there is several SrcDir and only use SrcDir if there is exactly one.

Done in 8ee6760. resolveFilePath() now counts directory-type SrcDir entries (those not ending with .java) and only combines with sourcepath when there is exactly one such entry. When there are zero or multiple directory-type entries, it falls back to the raw sourcepath unchanged.

Copilot AI changed the title FindbugsParser: combine SrcDir with sourcepath to produce complete file paths fix: combine SrcDir with sourcepath in FindbugsParser to produce complete file paths Mar 7, 2026
@tomasbjerre
Copy link
Copy Markdown
Owner

@copilot the spotbugs-main.xml has several SrcDir, i want that case handled just like before. Only change behavior for when there is exactly one SrcDir.

…xactly one

Co-authored-by: tomasbjerre <439571+tomasbjerre@users.noreply.github.com>
Copy link
Copy Markdown
Contributor Author

Copilot AI commented Mar 7, 2026

@copilot the spotbugs-main.xml has several SrcDir, i want that case handled just like before. Only change behavior for when there is exactly one SrcDir.

Fixed in 9d446d8. resolveFilePath() now checks the total count of all SrcDir entries and only combines with sourcepath when there is exactly one in total (and it's a directory). Since spotbugs-main.xml has many SrcDir entries, it falls back to the raw sourcepath unchanged. testThatViolationsCanBeParsedFromSpotbugs2 is also restored to the original assertion (se/bjurr/violations/lib/reports/ReportsFinder.java).

@tomasbjerre
Copy link
Copy Markdown
Owner

@copilot there is no test case for the use case in original issue

…rcDir exists

Co-authored-by: tomasbjerre <439571+tomasbjerre@users.noreply.github.com>
Copy link
Copy Markdown
Contributor Author

Copilot AI commented Mar 7, 2026

@copilot there is no test case for the use case in original issue

Added in afb90be. New fixture spotbugs-one-srcdir.xml has exactly one directory SrcDir (/builds/my-project/module-a/src/main/java) and a BugInstance with sourcepath="com/example/Foo.java". The new test testThatSrcDirIsCombinedWithSourcepathWhenExactlyOneSrcDir asserts that violation.getFile() returns /builds/my-project/module-a/src/main/java/com/example/Foo.java.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • groovy.jfrog.io
    • Triggering command: /usr/lib/jvm/temurin-17-jdk-amd64/bin/java /usr/lib/jvm/temurin-17-jdk-amd64/bin/java --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.lang.invoke=ALL-UNNAMED --add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.prefs/java.util.prefs=ALL-UNNAMED --add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED --add-exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED --add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.prefs/java.util.prefs=ALL-UNNAMED --add-opens=java.base/java.nio.charset=ALL-UNNAMED --add-opens=java.base/java.net=ALL-UNNAMED --add-opens=java.base/java.util.concurrent=ALL-UNNAMED --add-opens=java.base/java.util.concurrent.atomic=ALL-UNNAMED --add-opens=java.xml/javax.xml.namespace=ALL-UNNAMED --add-opens=java.base/java.time=ALL-UNNAMED -XX:MaxMetaspaceSize=384m -XX:&#43;HeapDumpOnOutOfMemoryError -Xms256m -Xmx512m -Dfile.encoding=UTF-8 (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

@tomasbjerre tomasbjerre marked this pull request as ready for review March 7, 2026 15:48
@tomasbjerre tomasbjerre merged commit 73e10ce into master Mar 7, 2026
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

FindbugsParser does not combine SrcDir with sourcepath

2 participants