Search code examples
javadependency-injectionguice

Guice detect unused bindings


I just inherited a big code base. I am cleaning up and trying to remove unnecessary dependencies.

Is there a way to find unnecessary dependencies defined in an injector?


Solution

  • You can use the Elements SPI, which allows you to traverse Guice's bindings in a running Injector. Remember, however, that Guice reflectively evaluates your tree at runtime. This allows you to add bindings and to depend on JIT (Just-In-Time) bindings, but also makes it so Guice might not ever be aware of classes you do not depend on through your injector.

    In the pathological case, you could have no modules defined whatsoever and depend on everything through JIT bindings, at which point any unused binding detector would return a null set (false negatives). Conversely, if you use getInstance or related Injector methods heavily but do not exercise them before scanning for unused deps, you might return many dependencies that wind up being unsafe to remove (false positives). This is especially true because Injector is injectable, so if you have an adapter to a legacy service locator (etc) you may find it difficult to anticipate all the ways your Injector is being used.

    To help avoid surprises, you might call requireExplicitBindings(), which applies to the entire Injector and its children but not its parents or siblings. This would cause all JIT bindings to need definition, even if only through an untargeted binding. You might also scan for getInstance, getProvider, and getMembersInjector, and injectMembers calls on Injector and reduce them through refactoring.

    An existing solution seems to be publicly available in bonifaido's guice-unused github tree, which avoids some of the problems above by explicitly requesting your root binding requests and reusing Guice's built-in dependency grapher transitive visitor. Disclaimer: This is not my code. It's simple enough, but I cannot warrant either its safety or the status of its intellectual property.