fix: index java_proto_library classes in IDE#394
Conversation
bded939 to
bf15d7d
Compare
|
This improves code completion somewhat (basically never showing before) but I still have to type 5-6 characters before I get a suggestion. |
…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>
bf15d7d to
da6042f
Compare
|
Still working on more fixes. |
|
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 |
|
Ctrl+Space shows autocomplete just fine so the only issue is that it doesn't autocomplete after just a |
ab0b1af to
0fafa1b
Compare
|
Unable to reproduce the issue. |
This should be merged after #391
Summary
java_proto_libraryrules 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 defaultfastbuild/bin. This caused three related issues — fixed here together.Fix 1: Populate
java_common.jarsforjava_proto_libraryfromfull_compile_jars(aspect)java_proto_librarytargets have emptyJavaInfo.java_outputsbecause the actual compilation (bazel_java_proto_aspect) runs in the transitioned config and its outputs are not surfaced throughjava_outputs. As a result,java_common.jarswas always empty for these targets, andJavaLanguagePlugincreated no library entries — so proto-generated Java classes never appeared in the IDE classpath.Fix: In
java_info.bzl.template, whenjarsis empty and the rule kind isjava_proto_library, fall back toJavaInfo.full_compile_jarsfiltered to class jars owned by the current package only. The package filter is essential —full_compile_jarsis transitive and without filtering everyjava_proto_librarywould register its entire transitive dependency tree, flooding the project model with hundreds of duplicate library entries.Fix 2: Prefer jar-bearing
TargetInfonodes in conflict resolution (TargetInfoReader)When the BSP aspect runs alongside
bazel_java_proto_aspect, both produce.bsp-info.textprotofiles 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
jarsListbefore falling back to smallest-by-size. The resolution logic is extracted into a testablecompanion objectfunction 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). Addingsibling = raw_jdeps_fileplaces 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
?: continuethat 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
TargetInfoReaderTest— covers all conflict-resolution branches including the proto shadow-graph casejava_proto_librarydeps and verify generated Java classes (e.g.Account.Builder) appear in autocompletejava_testtargets with the same basename in a single BUILD package build without action conflicts🤖 Generated with Claude Code