Shading is a part of packaging the library dependency: you'd use a rewriting tool repackage that library to include the dagger.internal
from Dagger 2.13 under a new name (say librarynamehere.shaded.dagger.internal
) that changes all references inside the library to use the new name. This would allow the two versions of dagger.internal
to coexist in your library, but you should only try this if you can't upgrade your versions of Dagger to match in the library and in your application.
As in this answer, a refactor in Dagger 2.14 removed the method MembersInjector.injectMembers. Code generated with 2.14 and beyond shouldn't call into this method.
What's happening here is that the library you're consuming has packaged up Dagger-generated code that assumes the presence of MembersInjector.injectMembers
as it was prior to 2.14. With the upgrade to 2.19, the method is absent, so the generated code is broken.
This is particularly tricky because the removal of this method is arguably a semantic versioning breaking change, but has a minor version increase that package management libraries might assume is non-breaking. In fairness to Dagger, the intent is that libraries do not ship generated code, but instead document their usage or allow the consuming application to generate code with matching libraries:
There's no guarantee that the generated code (i.e. factories) work well with each other across versions. We don't have any way of testing that. It's a generally good idea that any libraries that are intended to use Dagger in tandem are using the same version of Dagger.
If a library you don't own is passing along Dagger codegen to you and isn't documenting it, that's a bad idea on the library owners part.
If you have the option to upgrade or recompile the library with a newer version of Dagger, ideally one that matches the outer version of Dagger you're using, that would solve the problem. Likewise, if you were to keep your outer version of Dagger to match the version in the dependency. Those would be more ideal than shading.
As in the Software Engineering SE question What is a "shaded" Java dependency?, shading refers to repackaging and/or renaming a Java resource using a tool like jarjar. The idea here is to package a copy of the 2.13 dagger.internal
library with the dependency, rewriting the bytecode in the library to consume the repackaged version of Dagger rather than the new one.
However, the cheapest (but most fragile) solution is "shadowing": adding a file in your source directory for dagger/internal/MembersInjectors.java
matching the version of Dagger you're using but readding the missing injectMembers
method. Assuming that your build system prefers local files over dependencies when setting up the classpath, your local file will be found before the Dagger-provided equivalent. This might work, but could then become a merge hazard later, and might cause weird errors if MembersInjectors changes in yet-newer versions of Dagger: I'd try this only for very temporary code.
See also: Java Class Shadowing and Shading by Ammar Khaku on Medium