Status Update
Comments
em...@google.com <em...@google.com>
je...@google.com <je...@google.com>
ga...@google.com <ga...@google.com> #2
I can reproduce this (thanks for the repro project!)
It looks like the problem is that the desugared api list from r8 contains this entry:
java/util/Collection#removeIf(Ljava/util/function/Predicate;)Z
but the bytecode here doesn't match -- it's java/util/ArrayList. Collection isn't a directly implemented interface or a direct super class, it's an interface on the super super class. The most efficient thing runtime wise would be for the signature list to inline this method on all implemented subclasses. But I should probably at least for now go and make the desugared API lookup do something similar to what it does for API lookup -- search through all super classes and interfaces as well. This isn't a new problem, so I'm very surprised this hasn't come up before (or it has, and I've forgotten).
ka...@gmail.com <ka...@gmail.com> #3
(I have a pending CL that was working to improve the handling of fields now that r8 handles desugaring fields, I'll try to dust that off and combine the fix in there.)
ga...@google.com <ga...@google.com> #4
I went to implement this, and hooked up inheritance search when analyzing the source file containing the call.
However, lint also handles the case where the library being analyzed is not using core library desugaring (for example, it may be a plain Java library). But when that library is consumed in a downstream app module, where library desugaring is turned on, lint then processes the partial results from the library and filters each violation through the desugaring allowlist.
At this point, it's tricky to do the inheritance search -- this happens when we no longer have a compilation environment and can do class inheritance lookups. So there are three possible solutions.
First, we pay the cost up front -- even when you're not using core library desugaring, we record whether the method is potentially library desugared if turned on. (This is also tricky because at this point we don't know which exact desugaring library version is used, which determines the exact list of APIs).
Or, more expensively, for every API violation of this type we store all the potential super class and interface names for each result...
Or, we handle this in the code which generates the desugaring API list, inlining all subclasses affected. This could be quite a long list, but on the other hand this list is really only intended to be machine readable.
ka...@gmail.com <ka...@gmail.com> #5
This is partially fixed now; it's fully fixed for the sample project, but in the scenario I described in comment 4, it works if you also configure library desugaring to be on in the library.
ga...@google.com <ga...@google.com> #6
likely related:
Objects.requireNonNullElse
Objects.requireNonNullElseGet
are now also showing this same false positive warning.
Android Studio Koala | 2023.3.2 Canary 2 gradle 8.6 plugin: 8.3.1
Description
DESCRIBE THE ISSUE IN DETAIL:
AGP failed during syncing project, where there is composite build (includeBuild) of project with, in order, another composite build (i.e. nested composite build).
STEPS TO REPRODUCE:
includeBuild("../lib1")
includeBuild("../lib2")
Full example is attached.
Studio Build: Android Studio Giraffe | 2022.3.1 Canary 11 (Build #AI-223.8836.35.2231.9848316, built on March 30, 2023)
Version of Gradle Plugin: 8.1.0-alpha11
Version of Gradle: 8.0
Version of Java: JetBrains Runtime version 17.0.6
OS: Windows 11
The cause of problem is
in com.android.build.gradle.internal.ide.v2.ModelBuilder
.Look into method
getBuildName()
. There is conditionit.projectDir == currentGradle.rootProject.projectDir
According to Gradle docs, nested composite build structure is flattened, i.e. all the included (and syb-included) projects have same root. See Gradle updated docs inhttps://github.com/gradle/gradle/pull/24469/files#diff-07fc669ece55f938ee36f360129142a0576f95381ffe9c7f737ce6fe69499993
So when executing on sub-included project (lib2) the condition above will be false, because
parentGradle
will beapp
instead oflib1
parentGradle.includedBuilds
will belib1
instead oflib2
As a result,
it.projectDir === lib1
, whencurrentGradle.rootProject.projectDir === lib2
So it is needed to fix
getBuildName
to solve the problem.