[Hilt] `enableExperimentalClasspathAggregation` breaks lint
See original GitHub issueEnabling enableExperimentalClasspathAggregation
in a multi-module project breaks app:lint
task.
$ ./gradlew :app:lintRelease
FAILURE: Build failed with an exception.
* What went wrong:
Could not determine the dependencies of task ':app:lintRelease'.
> Could not resolve all files for configuration ':app:debugRuntimeClasspath'.
> Failed to transform full.jar (project :ui) to match attributes {artifactType=jar-for-dagger, com.android.build.api.attributes.BuildTypeAttr=debug, com.android.build.api.attributes.VariantAttr=debug, org.gradle.libraryelements=jar, org.gradle.usage=java-runtime}.
> Execution failed for JetifyTransform: /x/y/z/dep/build/intermediates/full_jar/debug/full.jar.
> Transform's input file does not exist: /x/y/z/dep/build/intermediates/full_jar/debug/full.jar. (See https://issuetracker.google.com/issues/158753935)
This issue has probably the same cause as https://github.com/google/dagger/issues/2288 but IMO is more important because lint usually runs automatically on CI server and cannot be simply disabled/removed.
It might be that it is an issue in lint (see https://issuetracker.google.com/issues/158060799) but it occurs only after integrating Hilt with enableExperimentalClasspathAggregation = true
. And this makes me feel that it should be fixed in Hilt.
Dagger Hilt version: 2.32-alpha AGP version: 4.1.1
Issue Analytics
- State:
- Created 3 years ago
- Reactions:5
- Comments:9 (3 by maintainers)
Top Results From Across the Web
[Hilt] `enableExperimentalClasspathAggregation` breaks lint -
Enabling enableExperimentalClasspathAggregation in a multi-module project breaks app:lint task. $ ./gradlew :app:lintRelease FAILURE: Build ...
Read more >Gradle Build Setup - Dagger
To use Hilt, add the following build dependencies to the Android Gradle module's ... Note that this option replaces enableExperimentalClasspathAggregation ...
Read more >Room Dao whit Hilt Broke after adding a fragment
Finally, i solved it by updating gradle dagger hilt plugin and dependencies, from 2.38.1 to 2.42. In any case, i don´t understand why...
Read more >Lint UnusedResources incorrectly fails when using ...
Things only broke in 7.0+. For our use case, it would be completely reasonable to assume that if the binding class is used,...
Read more >dagger.hilt.android.plugin.HiltGradlePlugin.kt Maven / Gradle ...
package dagger.hilt.android.plugin import com.android.build.api.component. ... to ask users to disable lint when enableExperimentalClasspathAggregation is ...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
Ideally we don’t want to have this flag at all but we are trying to address the high cognitive load and decision making process of using
api
vsimplementation
with Hilt. Specifically, even if the rules documented by Gradle are well-defined, it is still not easy to reason or make a decision based solely on the user code, since you would need to take into account Dagger/Hilt generated code which makes it very difficult for inexperienced users.Let me explain the issue as we understand it, what the flag does and why we believe using api all over might not be the best approach.
The issue relates to Gradle module boundaries so we’ll need a chain of dependencies:
app
->repo
->httpLibrary
.app
is the ‘root’ module, it defines the@HiltAndroidApp
and depends onrepo
:repo
has public APIs used by the app and internally uses a http library:httpLibrary
is a 3rd party dependency fetched from a maven repository. Note thatHttpClient
is a type that is never exposed as part ofrepo
’s API.If
repo
declares its dependency asimplementation
and since Dagger takes a look atRepo
, things will fail with a ‘not found type’ because none of the types and classes fromhttpLibrary
are in the compile classpath ofapp
. This is not so bad, since you get a compile error and even though it can be hard to understand the issue based on the error message, it can be fixed, but there are other more dangerous cases where the errors are silent, specifically with Hilt.Consider a multibinding case, where you have a module that contributes to a multibinding.
In our
repo
module we now have:repo
now depends on asqlCache
Gradle module which contains:A user might end up reasoning that
implementation
is the right choice becauseSQLCache
is an implementation class that is exposed as theCache
interface, a common interface used byrepo
andsqlCache
. In this case however, because theSQLCacheModule
is not visible to the root (app
), the module will not be installed and the cache will not show up in the multibinding set. This is very dangerous because it becomes a runtime issue instead of a compilation error. The set will have a missing entry.The flag is an attempt to address the friction and the incompatibility of the recommendation vs what Dagger processes. This is done by gathering your dependencies and adding them as
compileOnly
to the root. In other words and using the examples above,app
, besides having animplementation
dependency onrepo
, it will also have acompileOnly
dependency tohttpLibrary
/sqlCache
.Using
api
all around is not the best solution either, because types are leaked in between modules, it increases the compile classpath at each node until the root, and more modules have to be compiled along the dependency line when a change is done in a leaf. Whereas the flag only increases the compile classpath at the root.Since the errors are silent in Hilt we need to do something. We could try detecting the issue and informing the user, making using
implementation
an error, but usingapi
has the disadvantages mentioned above. Given these tradeoffs, we decided it’d be best to offer a flag to opt-in into this behaviour that we wish we could just do automatically. Instead of expecting each user to know the internals of Dagger generated code so that they can make theirapi
vsimplementation
decision. We hope to make changes to AGP to make this more automatic and to remove the current issues (such as Lint) and hackiness around the flag implementation.Hi, I have another issue switching to hilt {enableAggregatingTask = true}. This change solves the Lint error but I have a new error with product flavors when run dependencies task. When I put a flavor with name axxx and another bxxx it doesnt fail, but if I put a flavor that begins with “h” (“a” to “g” works) it throws me the following error.
Execution failed for task ‘:app:dependencies’.
this configuration fails !!
This works!!
“Hms” works too (capital)