Skip to content

fix: index java_proto_library classes in IDE#394

Closed
tboernerapex wants to merge 6 commits into
JetBrains:261from
tboernerapex:fix/java-proto-library-indexing
Closed

fix: index java_proto_library classes in IDE#394
tboernerapex wants to merge 6 commits into
JetBrains:261from
tboernerapex:fix/java-proto-library-indexing

Conversation

@tboernerapex

@tboernerapex tboernerapex commented May 11, 2026

Copy link
Copy Markdown

This should be merged after #391

Summary

java_proto_library rules apply a proto toolchain configuration transition, so their class jars are built in a -ST-<hash> output directory (e.g. darwin_arm64-fastbuild-ST-8c97a2cbca67/bin) rather than the default fastbuild/bin. This caused three related issues — fixed here together.

Fix 1: Populate java_common.jars for java_proto_library from full_compile_jars (aspect)

java_proto_library targets have empty JavaInfo.java_outputs because the actual compilation (bazel_java_proto_aspect) runs in the transitioned config and its outputs are not surfaced through java_outputs. As a result, java_common.jars was always empty for these targets, and JavaLanguagePlugin created no library entries — so proto-generated Java classes never appeared in the IDE classpath.

Fix: In java_info.bzl.template, when jars is empty and the rule kind is java_proto_library, fall back to JavaInfo.full_compile_jars filtered to class jars owned by the current package only. The package filter is essential — full_compile_jars is transitive and without filtering every java_proto_library would register its entire transitive dependency tree, flooding the project model with hundreds of duplicate library entries.

if not jars and provider and ctx.rule.kind == "java_proto_library":
    full_compile = [
        f for f in getattr(provider, "full_compile_jars", depset()).to_list()
        if not f.basename.endswith("-hjar.jar") and f.owner.package == ctx.label.package
    ]

Fix 2: Prefer jar-bearing TargetInfo nodes in conflict resolution (TargetInfoReader)

When the BSP aspect runs alongside bazel_java_proto_aspect, both produce .bsp-info.textproto files for the same label — one in the default config (jar-less) and one in the transitioned config (contains the speed jars). The previous conflict resolution always picked the smallest-by-size node, which was the empty shell, leaving the library without any jars.

Fix: Among JVM nodes, prefer those with non-empty jarsList before falling back to smallest-by-size. The resolution logic is extracted into a testable companion object function with unit tests.

Fix 3: Place materialized jdeps sibling to source file (get_jdeps)

ctx.actions.declare_file("materialized_" + basename) places the output in the package root, causing action conflicts when two targets in the same BUILD package share a basename (e.g. TypesTest.jdeps). Adding sibling = raw_jdeps_file places each materialized file next to the source jdeps in the target's own subdirectory.

Fix 4: Retain original path for non-existent output files (DefaultBazelOutputFileHardLinks)

The ?: continue that silently dropped files that don't exist on disk was changed to retain the original path, so the library entry stays registered even if the jar hasn't been downloaded. IntelliJ's VFS surfaces access errors rather than silently losing the jar from the classpath.

Test plan

  • Run TargetInfoReaderTest — covers all conflict-resolution branches including the proto shadow-graph case
  • Sync a Bazel project containing java_proto_library deps and verify generated Java classes (e.g. Account.Builder) appear in autocomplete
  • Verify no duplicate library entries for proto targets (project model size unchanged or reduced)
  • Verify two java_test targets with the same basename in a single BUILD package build without action conflicts

🤖 Generated with Claude Code

@tboernerapex tboernerapex marked this pull request as draft May 11, 2026 20:04
@tboernerapex tboernerapex force-pushed the fix/java-proto-library-indexing branch from bded939 to bf15d7d Compare May 11, 2026 20:07
@tboernerapex tboernerapex marked this pull request as ready for review May 11, 2026 20:07
@tboernerapex

Copy link
Copy Markdown
Author

This improves code completion somewhat (basically never showing before) but I still have to type 5-6 characters before I get a suggestion.

tboernerapex and others added 5 commits May 11, 2026 15:55
…g TargetInfo nodes

java_proto_library applies a proto toolchain configuration transition, causing
its class and source jars to land in a -ST-<hash> output directory instead of
the default bazel-bin. When the Bazel aspect produces multiple TargetInfo nodes
for the same label (shadow graph conflict), the previous heuristic of picking
the smallest node could select a jar-less shell, leaving the library empty and
breaking IntelliJ code completion for proto-generated classes.

Changes:
- TargetInfoReader: prefer JVM nodes with non-empty jarsList before falling back
  to smallest-by-size. Extracted into resolveConflict() for testability.
- DefaultBazelOutputFileHardLinks: retain original path (with a warning) when a
  jar file does not exist on disk, instead of silently dropping it from the
  library entry.
- Add TargetInfoReaderTest covering the proto shadow-graph conflict scenarios.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…icts

When two java_test targets in the same BUILD package share the same
basename (e.g. TypesTest), both previously declared their materialized
jdeps file as materialized_<basename>.jdeps in the package root,
causing Bazel to report conflicting actions for the same output path.

Adding `sibling = raw_jdeps_file` places each materialized file next to
its source jdeps file (which lives in a target-specific output subdirectory),
making the paths unique and eliminating the conflict.

Upstream intends to fix this but has not shipped a release yet; re-applying
locally until their fix lands.
…le_jars

java_proto_library produces no java_outputs of its own — the compiled class
jars (libproto-speed.jar) are generated by bazel_java_proto_aspect running in
a config-transitioned context and are not surfaced through JavaInfo.java_outputs.

As a result the aspect emitted an empty java_common.jars for these targets,
causing JavaLanguagePlugin to create a library with no class jars, which left
all proto-generated Java classes invisible to IntelliJ code completion.

When java_outputs is empty for a java_proto_library target, fall back to
full_compile_jars filtered to class jars (excluding -hjar.jar interface jars).
This makes libproto-speed.jar appear in java_common.jars and ensures it is
both registered as a library class jar and requested as a bsp-build-artifact.
full_compile_jars is transitive: a java_proto_library with N proto deps
includes all N speed jars, not just its own. Without the package filter,
every proto library registers its entire transitive dependency tree as
class jars, flooding the project model with ~460 duplicate entries and
making autocomplete extremely slow.

Filter to jars owned by the same Bazel package (f.owner.package ==
ctx.label.package) so each java_proto_library registers exactly the one
libproto-speed.jar it directly produces.
The logger.warn was added during debugging and is noisy in production
(emits one line per missing proto jar on every sync).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@tboernerapex tboernerapex changed the base branch from main to 261 May 11, 2026 20:55
@tboernerapex tboernerapex force-pushed the fix/java-proto-library-indexing branch from bf15d7d to da6042f Compare May 11, 2026 20:56
@tboernerapex tboernerapex marked this pull request as draft May 12, 2026 19:01
@tboernerapex

Copy link
Copy Markdown
Author

Still working on more fixes.

@tboernerapex

Copy link
Copy Markdown
Author

Well at this point i'm not sure what else to try. Some of the early changes on this PR did help the indexing but the last few commits seem to have done nothing. I was asked to repro in https://youtrack.jetbrains.com/issue/BAZEL-3169 but the example project isn't working (see the comments). With the first few changes in this PR I am now able to do fuzzy searching on the protobuf fields but nothing appears initially after you add a . after the variable name.

@tboernerapex

Copy link
Copy Markdown
Author

Ctrl+Space shows autocomplete just fine so the only issue is that it doesn't autocomplete after just a .

@tboernerapex tboernerapex force-pushed the fix/java-proto-library-indexing branch from ab0b1af to 0fafa1b Compare May 12, 2026 20:27
@tboernerapex

Copy link
Copy Markdown
Author

Unable to reproduce the issue.

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.

1 participant