Skip to content

fix(semanticdb-javac): report analysis exceptions as WARNING instead of ERROR#862

Open
rpalcolea wants to merge 1 commit intosourcegraph:mainfrom
rpalcolea:fix/report-exception-kind-warning
Open

fix(semanticdb-javac): report analysis exceptions as WARNING instead of ERROR#862
rpalcolea wants to merge 1 commit intosourcegraph:mainfrom
rpalcolea:fix/report-exception-kind-warning

Conversation

@rpalcolea
Copy link
Copy Markdown

reportException() was calling reporter.error() which uses Diagnostic.Kind.ERROR, causing javac to exit non-zero and fail the build. The surrounding catch block explicitly states 'we don't want to stop the compilation' — this change makes the implementation match the intent.

Adds SemanticdbReporter.warning() for plugin-internal failures, and updates SemanticdbTaskListener.reportException() to use it. Intentional error paths (e.g. -no-relative-path:error mode) are unchanged.

Fixes builds for projects with partial classpaths (e.g. Apache Spark) where CompletionFailure for anonymous inner classes like DataType was breaking compileJava entirely.

Fixes #861

Test plan

What we're testing

SemanticdbTaskListener.reportException() previously emitted Diagnostic.Kind.ERROR,
causing javac to exit non-zero and fail the build when semanticdb-javac hit an internal
exception. After the fix it emits Kind.WARNING, so the build succeeds with partial
semanticdb output.


New unit test

PartialClasspathSuite.scala in tests/unit/src/test/scala/tests/.

How it triggers reportException()

The test pre-creates the semanticdb output path (META-INF/semanticdb/example) as a
regular file instead of a directory. When SemanticdbTaskListener.writeSemanticdb()
calls Files.createDirectories(output.getParent()), it throws FileAlreadyExistsException
(a subtype of IOException). The existing catch (IOException e) block catches it and
calls reportException()reporter.warning()trees.printMessage(Kind.WARNING, ...).

This approach is JDK-version-agnostic. An earlier design attempted to trigger
CompletionFailure by deleting an inner class file from the classpath, but Java 21+
handles missing inner class files silently (omitting them rather than throwing), so
that approach was not reliable across JDK versions.

Test 1 — compilation succeeds with a warning

  • Blocks the output directory, compiles UsesA.java
  • Asserts result.isSuccess == true
  • Asserts result.stdout.contains("warning:")
  • Asserts !result.stdout.contains("\nerror:")

Test 2 — semanticdb still produced for healthy files

  • Compiles UsesA.java (triggers exception) alongside Healthy.java (clean)
  • Asserts result.isSuccess == true
  • Asserts Healthy.java has a semanticdb document in the output

Existing tests that continue to pass

Full unit suite was run on the branch — all tests pass:

sbt "unit/test"

Key suites that exercise compilation behaviour:

  • OverridesSuite — type resolution across files
  • JavacClassesDirectorySuite — targetroot output
  • SnapshotCommandSuite — end-to-end symbol output

…of ERROR

reportException() was calling reporter.error() which uses Diagnostic.Kind.ERROR,
causing javac to exit non-zero and fail the build. The surrounding catch block
explicitly states 'we don't want to stop the compilation' — this change makes
the implementation match the intent.

Adds SemanticdbReporter.warning() for plugin-internal failures, and updates
SemanticdbTaskListener.reportException() to use it. Intentional error paths
(e.g. -no-relative-path:error mode) are unchanged.

Fixes builds for projects with partial classpaths (e.g. Apache Spark) where
CompletionFailure for anonymous inner classes like DataType was breaking
compileJava entirely.

Fixes sourcegraph#861

Signed-off-by: Roberto Perez Alcolea <rperezalcolea@netflix.com>
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.

semanticdb-javac: exceptions in reportException() use Kind.ERROR, breaking compilation for projects with partial classpaths (e.g. Spark)

1 participant