feat(java/gazelle): scaffold class-level dependency resolution#394
Conversation
Currently, the Java Gazelle plugin relies solely on package-level indexing for dependency resolution. This is inefficient for split packages in large corporate repositories, often requiring manual #gazelle:resolve directives. This change introduces the architecture for class-level resolution: Updates the resolution input pipeline to carry class-level import data alongside package data. Extends the Maven resolver to support querying by class name (with package fallback). Updates the resolution logic to prioritize precise class matches over broad package matches. This structure prepares the plugin for future improvements where class indices can be populated from jar files or external services, enabling automatic and precise resolution for split packages.
4f6a8fd to
071a9de
Compare
|
Have you profiled this? I did a similar proof of concept a while ago and it increased both the time taken and memory consumption pretty significantly... |
|
Having used the gazelle plugin on a number of projects (particularly those that are migrating multi-project Gradle/Maven repos), split packages are a common problem. It may be worth taking the memory hit regardless. I've not measured the change in resolution time. If it does increase significantly, perhaps we need to consider a different data structure for holding the data we need. |
|
Running a small benchmark on this repo, I get the following results (comparing this branch and This repo is pretty well-behaved, in that it doesn't have any split-packages so the memory consumption seems reasonable, but the timing difference seems surprising. I'll investigate. |
This means that in the happy case (where there are no split packages) the plugin is now as fast and as memory efficient as without them, but memory (and time) will increase as the number of split packages grows.
This change adds class-level resolution as a fallback when package resolution is ambiguous: 1. During generation, cache each rule's exported classes and testonly status 2. On ambiguous package resolution, build a per-package class index lazily 3. Resolve individual class imports to their specific providing target 4. Maintain prod/test separation (test rules can see both, prod only sees prod) Performance: The class index is built lazily per-package, only for packages with multiple providers. Classes are NOT added to Gazelle's global RuleIndex, avoiding O(classes) overhead for non-split-package resolution. Maven collisions still produce the original helpful error messages with `# gazelle:resolve` hints, as these cannot be resolved via class-level lookup.
|
With the updates here. the difference between |
|
I did some profiling on our repository to understand what impact this would have. I've submitted the scripts used to do the profiling in #403. I need to review the units (KB/MB) used by the script but this should give you an idea. Summary
Here are the details from running Detailsmain gazelle-class-names |
|
I updated the comment above to reflect that the behavior adding |
|
Is this with the most recent commits, or before I added them yesterday? |
It is based on e490fee which is your last commit from yesterday. |
|
@illicitonion, I think that addresses the size and speed concerns. |




Currently, the Java Gazelle plugin relies solely on package-level indexing for dependency resolution. This is inefficient for split packages in large corporate repositories, often requiring manual #gazelle:resolve directives.
This change introduces the architecture for class-level resolution:
Updates the resolution input pipeline to carry class-level import data alongside package data. Extends the Maven resolver to support querying by class name (with package fallback). Updates the resolution logic to prioritize precise class matches over broad package matches.