{"action":"closed","issue":{"url":"https://api.github.com/repos/gradle/gradle/issues/6985","repository_url":"https://api.github.com/repos/gradle/gradle","labels_url":"https://api.github.com/repos/gradle/gradle/issues/6985/labels{/name}","comments_url":"https://api.github.com/repos/gradle/gradle/issues/6985/comments","events_url":"https://api.github.com/repos/gradle/gradle/issues/6985/events","html_url":"https://github.com/gradle/gradle/issues/6985","id":365647742,"node_id":"MDU6SXNzdWUzNjU2NDc3NDI=","number":6985,"title":"DefaultConfiguration#createCopy shouldn't share mutable listener list","user":{"login":"dansanduleac","id":222827,"node_id":"MDQ6VXNlcjIyMjgyNw==","avatar_url":"https://avatars1.githubusercontent.com/u/222827?v=4","gravatar_id":"","url":"https://api.github.com/users/dansanduleac","html_url":"https://github.com/dansanduleac","followers_url":"https://api.github.com/users/dansanduleac/followers","following_url":"https://api.github.com/users/dansanduleac/following{/other_user}","gists_url":"https://api.github.com/users/dansanduleac/gists{/gist_id}","starred_url":"https://api.github.com/users/dansanduleac/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dansanduleac/subscriptions","organizations_url":"https://api.github.com/users/dansanduleac/orgs","repos_url":"https://api.github.com/users/dansanduleac/repos","events_url":"https://api.github.com/users/dansanduleac/events{/privacy}","received_events_url":"https://api.github.com/users/dansanduleac/received_events","type":"User","site_admin":false},"labels":[{"id":460356597,"node_id":"MDU6TGFiZWw0NjAzNTY1OTc=","url":"https://api.github.com/repos/gradle/gradle/labels/a:bug","name":"a:bug","color":"d93f0b","default":false},{"id":478384995,"node_id":"MDU6TGFiZWw0NzgzODQ5OTU=","url":"https://api.github.com/repos/gradle/gradle/labels/from:contributor","name":"from:contributor","color":"0052cc","default":false},{"id":281294573,"node_id":"MDU6TGFiZWwyODEyOTQ1NzM=","url":"https://api.github.com/repos/gradle/gradle/labels/in:dependency-management","name":"in:dependency-management","color":"d4c5f9","default":false}],"state":"closed","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":2,"created_at":"2018-10-01T21:19:38Z","updated_at":"2018-11-06T23:16:24Z","closed_at":"2018-11-06T23:16:24Z","author_association":"CONTRIBUTOR","body":"<!--- \r\nPlease follow the instructions below. We receive dozens of issues every week, so to stay productive, we will close issues that don't provide enough information. \r\n\r\nPlease open Android-related issues on the Android Issue Tracker at https://source.android.com/source/report-bugs\r\nPlease open Kotlin DSL-related issues at https://github.com/gradle/kotlin-dsl/issues\r\nPlease open Gradle Native-related issues at https://github.com/gradle/gradle-native/issues\r\n-->\r\n\r\n<!--- Provide a brief summary of the issue in the title above -->\r\n\r\n`DefaultConfiguration#createCopy` [replaces](https://github.com/gradle/gradle/blob/b4d8d5d170bb4ba516e88d7fe5647e2323d791dd/subprojects/dependency-management/src/main/java/org/gradle/api/internal/artifacts/configurations/DefaultConfiguration.java#L792) the fresh anonymous broadcaster (`dependencyResolutionListeners`) that each new configuration gets with the one from the copied configuration.\r\n\r\nThis in conjunction with the fact that after resolve, [the listener set is cleared](https://github.com/gradle/gradle/blob/b4d8d5d170bb4ba516e88d7fe5647e2323d791dd/subprojects/dependency-management/src/main/java/org/gradle/api/internal/artifacts/configurations/DefaultConfiguration.java#L544), means that only one of the original and copied configrations will get a non-empty listener, depending on which one is resolved first.\r\n\r\n### Expected Behavior\r\n<!--- If you're describing a bug, tell us what should happen -->\r\n<!--- If you're suggesting a change/improvement, tell us how it should work -->\r\n\r\nEach configuration, whether copied or not, should have its own independent `dependencyResolutionListeners` that will get called with that configuration's `ResolvableDependencies` instance.\r\n\r\nIf preserving the original listeners is important, then the listener set should be shallow-copied into a new set that the copied configuration owns.\r\n\r\n### Current Behavior\r\n<!--- If describing a bug, tell us what happens instead of the expected behavior -->\r\n<!--- If suggesting a change/improvement, explain the difference from current behavior -->\r\n\r\nOnly one of the configurations gets to trigger the listeners for both configurations.\r\nThis leads to confusion and hacks like [what nebula.dependency-recommender does](https://github.com/nebula-plugins/nebula-gradle-interop/blob/master/src/main/kotlin/com/netflix/nebula/interop/configurations.kt) (that function called [here](https://github.com/nebula-plugins/nebula-dependency-recommender-plugin/blob/a8ad219cd8cc4c323327db85902a7b6af0bfb992/src/main/groovy/netflix/nebula/dependency/recommender/DependencyRecommendationsPlugin.java#L91)).\r\n\r\n### Context\r\n<!--- How has this issue affected you? What are you trying to accomplish? -->\r\n<!--- Providing context helps us come up with a solution that is most useful in the real world -->\r\n\r\nI am trying to `copyRecursive` the `default` configuration in all subprojects, such that I can resolve them from a root project configuration and afterwards add constraints on the original subprojects' `default` configurations.\r\nThis doesn't work with `nebula.dependency-recommender` (it never gets applied to the copied configurations) because it will never have its listener called with the correct `ResolvableDependencies` for the copied configuration.\r\n\r\n### Steps to Reproduce (for bugs)\r\n<!--- Provide a self-contained example project (as an attached archive or a Github project). -->\r\n<!--- In the rare cases where this is infeasible, we will also accept a detailed set of instructions. -->\r\n\r\n```gradle\r\nconfigurations {\r\n  foo\r\n}\r\n\r\ndef fooCopy = configurations.foo.copyRecursive()\r\nconfigurations.add(fooCopy)\r\n\r\nconfigurations.foo.incoming.beforeResolve { incoming ->\r\n  println(\"beforeResolved for foo called with: \" + incoming)\r\n}\r\n\r\nfooCopy.incoming.beforeResolve { incoming ->\r\n  println(\"beforeResolved for fooCopy called with: \" + incoming)\r\n}\r\n```\r\n\r\nWill print:\r\n\r\n```\r\n> Task :dependencies\r\n\r\n------------------------------------------------------------\r\nRoot project\r\n------------------------------------------------------------\r\n\r\nfoo\r\nbeforeResolved for foo called with: dependencies ':foo'\r\nbeforeResolved for fooCopy called with: dependencies ':foo'\r\nNo dependencies\r\n\r\nfooCopy\r\nNo dependencies\r\n```\r\n\r\n### Your Environment\r\n<!--- Include as many relevant details about the environment you experienced the bug in -->\r\n<!--- A build scan `https://scans.gradle.com/get-started` is ideal -->\r\n * Build scan URL: https://gradle.com/s/az7lcdu766rfk"}}
{"actor":{"display_login":"bigdaz"}}