@@ -205,68 +205,6 @@ subprojects {
205205 jetty_alpn_agent : ' org.mortbay.jetty.alpn:jetty-alpn-agent:2.0.10'
206206 ]
207207
208- // A util function to config guava dependency with transitive dependencies
209- // properly resolved for the failOnVersionConflict strategy.
210- guavaDependency = { configurationName ->
211- dependencies. " $configurationName " (libraries. guava) {
212- exclude group : ' com.google.code.findbugs' , module : ' jsr305'
213- exclude group : ' com.google.errorprone' , module : ' error_prone_annotations'
214- exclude group : ' org.codehaus.mojo' , module : ' animal-sniffer-annotations'
215- }
216- dependencies. " $configurationName " libraries. errorprone
217- dependencies. runtimeOnly libraries. animalsniffer_annotations
218- dependencies. runtimeOnly libraries. jsr305
219- }
220-
221- // A util function to config opencensus_api dependency with transitive
222- // dependencies properly resolved for the failOnVersionConflict strategy.
223- censusApiDependency = { configurationName ->
224- dependencies. " $configurationName " (libraries. opencensus_api) {
225- exclude group : ' com.google.code.findbugs' , module : ' jsr305'
226- exclude group : ' com.google.guava' , module : ' guava'
227- // we'll always be more up-to-date
228- exclude group : ' io.grpc' , module : ' grpc-context'
229- }
230- dependencies. runtimeOnly project(' :grpc-context' )
231- dependencies. runtimeOnly libraries. jsr305
232- guavaDependency ' runtimeOnly'
233- }
234-
235- // A util function to config opencensus_contrib_grpc_metrics dependency
236- // with transitive dependencies properly resolved for the failOnVersionConflict
237- // strategy.
238- censusGrpcMetricDependency = { configurationName ->
239- dependencies. " $configurationName " (libraries. opencensus_contrib_grpc_metrics) {
240- exclude group : ' com.google.code.findbugs' , module : ' jsr305'
241- exclude group : ' com.google.guava' , module : ' guava'
242- // we'll always be more up-to-date
243- exclude group : ' io.grpc' , module : ' grpc-context'
244- }
245- dependencies. runtimeOnly project(' :grpc-context' )
246- dependencies. runtimeOnly libraries. jsr305
247- guavaDependency ' runtimeOnly'
248- }
249-
250- googleOauth2Dependency = { configurationName ->
251- dependencies. " $configurationName " (libraries. google_auth_oauth2_http) {
252- exclude group : ' com.google.guava' , module : ' guava'
253- exclude group : ' io.grpc' , module : ' grpc-context'
254- exclude group : ' io.opencensus' , module : ' opencensus-api'
255- }
256- dependencies. runtimeOnly project(' :grpc-context' )
257- censusApiDependency ' runtimeOnly'
258- guavaDependency ' runtimeOnly'
259- }
260-
261- // A util function to config perfmark dependency with transitive
262- // dependencies properly resolved for the failOnVersionConflict strategy.
263- perfmarkDependency = { configurationName ->
264- dependencies. " $configurationName " (libraries. perfmark) {
265- exclude group : ' com.google.errorprone' , module : ' error_prone_annotations'
266- }
267- dependencies. runtimeOnly libraries. errorprone
268- }
269-
270208 appendToProperty = { Property<String > property , String value , String separator ->
271209 if (property. present) {
272210 property. set(property. get() + separator + value)
@@ -276,25 +214,6 @@ subprojects {
276214 }
277215 }
278216
279- configurations {
280- // Detect Maven Enforcer's dependencyConvergence failures. We only
281- // care for artifacts used as libraries by others.
282- if (isAndroid && ! (project. name in [' grpc-android-interop-testing' ])) {
283- releaseRuntimeClasspath {
284- resolutionStrategy. failOnVersionConflict()
285- }
286- }
287- if (! isAndroid && ! (project. name in [
288- ' grpc-benchmarks' ,
289- ' grpc-interop-testing' ,
290- ' grpc-gae-interop-testing-jdk8' ,
291- ])) {
292- runtimeClasspath {
293- resolutionStrategy. failOnVersionConflict()
294- }
295- }
296- }
297-
298217 // Disable JavaDoc doclint on Java 8. It's annoying.
299218 if (JavaVersion . current(). isJava8Compatible()) {
300219 allprojects {
@@ -406,6 +325,19 @@ subprojects {
406325 }
407326 }
408327
328+ plugins. withId(" java-library" ) {
329+ // Detect Maven Enforcer's dependencyConvergence failures. We only care
330+ // for artifacts used as libraries by others with Maven.
331+ tasks. register(' checkUpperBoundDeps' ) {
332+ doLast {
333+ requireUpperBoundDepsMatch(configurations. runtimeClasspath, project)
334+ }
335+ }
336+ tasks. named(' compileJava' ) {
337+ dependsOn checkUpperBoundDeps
338+ }
339+ }
340+
409341 plugins. withId(" me.champeau.gradle.jmh" ) {
410342 dependencies {
411343 jmh ' org.openjdk.jmh:jmh-core:1.19' ,
@@ -582,3 +514,56 @@ subprojects {
582514 }
583515 }
584516}
517+
518+ class DepAndParents {
519+ DependencyResult dep
520+ List<String > parents
521+ }
522+
523+ /**
524+ * Make sure that Maven would select the same versions as Gradle selected.
525+ * This is essentially the same as if we used Maven Enforcer's
526+ * requireUpperBoundDeps for our artifacts.
527+ */
528+ def requireUpperBoundDepsMatch (Configuration conf , Project project ) {
529+ // artifact name => version
530+ Map<String ,String > golden = conf. resolvedConfiguration. resolvedArtifacts. collectEntries {
531+ ResolvedArtifact it ->
532+ ModuleVersionIdentifier id = it. moduleVersion. id
533+ [id. group + " :" + id. name, id. version]
534+ }
535+ // Breadth-first search like Maven for dependency resolution
536+ Queue<DepAndParents > queue = new ArrayDeque<> ()
537+ conf. incoming. resolutionResult. root. dependencies. each {
538+ queue. add(new DepAndParents (dep : it, parents : [project. displayName]))
539+ }
540+ Set<String > found = new HashSet<> ()
541+ while (! queue. isEmpty()) {
542+ DepAndParents depAndParents = queue. remove()
543+ ResolvedDependencyResult result = (ResolvedDependencyResult ) depAndParents. dep
544+ ModuleVersionIdentifier id = result. selected. moduleVersion
545+ String artifact = id. group + " :" + id. name
546+ if (found. contains(artifact))
547+ continue
548+ found. add(artifact)
549+ String version
550+ if (result. requested instanceof ProjectComponentSelector ) {
551+ ProjectComponentSelector selector = (ProjectComponentSelector ) result. requested
552+ version = project. findProject(selector. projectPath). version
553+ } else {
554+ version = ((ModuleComponentSelector ) result. requested). version
555+ }
556+ String goldenVersion = golden[artifact]
557+ if (goldenVersion != version && " [$goldenVersion ]" != version) {
558+ throw new RuntimeException (
559+ " Maven version skew: $artifact ($version != $goldenVersion ) "
560+ + " Bad version dependency path: " + depAndParents. parents
561+ + " Run './gradlew $project . path :dependencies --configuration $conf . name ' "
562+ + " to diagnose" )
563+ }
564+ result. selected. dependencies. each {
565+ queue. add(new DepAndParents (
566+ dep : it, parents : depAndParents. parents + [artifact + " :" + version]))
567+ }
568+ }
569+ }
0 commit comments