-
Notifications
You must be signed in to change notification settings - Fork 89
Unused Dependency Rule
The unused dependency rule is an example of a complex dependency hygiene rule.
To apply the rule, add:
gradleLint.rules += 'unused-dependency'
The rule inspects compiled binaries emanating from your project's source sets looking for class references, and matches those references to the dependencies that you have declared in your dependencies block.
Specifically, the rule makes the following adjustments to dependencies:
- Removes unused dependencies
- Family-style jars like
com.amazonaws:aws-java-sdk
are removed, as they contain no code
- Promotes transitive dependencies that are used directly by your code to explicit first order dependencies
- This has the side effect of breaking up family style jars like
com.amazonaws:aws-java-sdk
into the parts that you are actually using, and adding those as first order dependencies
- Relocates dependencies to the 'correct' configuration
- Webjars are moved to the
runtime
configuration - Jars that contain no classes AND content outside of META-INF are moved to
runtime
- 'xerces', 'xercesImpl', 'xml-apis' should always be runtime scoped
- Service providers (jars containing META-INF/services) like
mysql-connector-java
are moved toruntime
if there is no provable compile-time reference - Dependencies are moved to the highest source set configuration possible. For example, 'junit' is relocated to
testCompile
unless there is an explicit dependency on it in the main source set (rare).
The rule uses a combination of ASM (to look for direct references) and reflection (to look for indirect type hierarchy references) to assess what is in use.
If your code refers to a dependency only via reflection, the dependency is best placed in the runtime
configuration, but the unused dependency rule will not see the reference.
Occasionally, you may find dependencies like com.amazonaws:aws-java-sdk
in third party or internal binary repositories that contain a dependency descriptor (POM or Ivy file) that lists a set of dependencies paired with a JAR that is virtually empty (no classes at a minimum). This is a simple technique to allow developers to pick up several libraries at once and provide a weak contract around version alignment for these libraries.
Generally, applications only use a subset of the libraries included in such families. The unnecessary dependencies included with the family both increase the footprint of the application itself. If the 'application' is actually itself a library, these unnecessary dependencies leak downstream to its users, increasing their footprint and potentially introducing breaking version conflict resolution problems.
Using the unused dependency rule, you can get coding quickly by including the family and later run the rule to strike all but the components you actually use (without having to know what each of these components' coordinates are).