google / play-services-plugins

Plugins to help with using Google Play services SDK.
https://developers.google.com/android/guides/overview
Apache License 2.0
471 stars 138 forks source link

StackOverflow in DependencyAnalyzer #247

Open jhansche opened 2 years ago

jhansche commented 2 years ago

Describe the bug Originally commented at https://github.com/google/play-services-plugins/issues/239#issuecomment-1242419037 but directed to create a separate issue.

DependencyAnalyzer gets stuck in a loop, possibly due to BOM version alignment references, leading to a StackOverflowError.

Desktop (please complete the following information): Gradle: 7.3 Android Gradle Plugin: 7.1.0 play-services-plugin: 4.3.14, 4.3.13, 4.3.12; works correctly in 4.3.10

Additional context

It may not be directly related, but in this case there is a module that uses a strictly("[17.0,)") version constraint on its firebase-messaging. I haven't tried recently, but it's possible that switching that to require("17.0.0") may help in this case.

The library also has its own platform/BOM artifact that is used for version alignment (the BOM references a constraint on the library, and the library adds the platform() dependency on the BOM project, so they are cross-referenced, as recommended in the Gradle documentation)

And finally, the app module enables Android viewBinding (hence the dataBindingMergeDependencyArtifacts* task, though I'm not sure that it's relevant):

android {
    buildFeatures {
        viewBinding = true
    }
}

Task failure:

:app:dataBindingMergeDependencyArtifactsDebug FAILED    
Dependency resolved to an incompatible version: Dependency(fromArtifactVersion=ArtifactVersion(groupId=com.example, artifactId=lib-push-fcm, version=1.2.3), toArtifact=Artifact(groupId=com.google.firebase, artifactId=firebase-messaging), toArtifactVersionString=[[17.0,)])    

with stack trace:

org.gradle.api.tasks.TaskExecutionException: Execution failed for task ':app:dataBindingMergeDependencyArtifactsDebug'. 
    at org.gradle.api.internal.tasks.execution.CatchExceptionTaskExecuter.execute(CatchExceptionTaskExecuter.java:38)   
    •••
Caused by: org.gradle.internal.event.ListenerNotificationException: Failed to notify dependency resolution listener.    
    at org.gradle.internal.event.AbstractBroadcastDispatch.dispatch(AbstractBroadcastDispatch.java:89)  
    •••
Caused by: java.lang.StackOverflowError: (No message provided)  
    at com.google.android.gms.dependencies.ArtifactDependencyManager.getDependencies(DataObjects.kt:127)    
    at com.google.android.gms.dependencies.DependencyAnalyzer.getNode(DependencyAnalyzer.java:82)   
    at com.google.android.gms.dependencies.DependencyAnalyzer.getNode(DependencyAnalyzer.java:90)   
    at com.google.android.gms.dependencies.DependencyAnalyzer.getNode(DependencyAnalyzer.java:90)   
    ...
    ...

The comments at #239 imply that the cycle should be removed, but that is how BOM/Platform version alignment works: library POM adds a scope=import dependency on the BOM artifact, and the BOM uses dependencyManagement constraints to refer to one or more library artifacts. It does create a cycle, but that's by design. Gradle handles the dependency resolution properly, so I don't think the problem is with the POM files.