Gradle dependency hierarchy in script - gradle

My goal is to print the dependencies of a gradle build including there hierarchy. The idea is to graphically build a dependency graph. The information I need would be the same as when I type gradle dependencies.
How can I achive this? Where do I get the information from, when I create my own task?

Perhaps this is what you're looking for:
project.configurations.compile.resolvedConfiguration.resolvedArtifacts.each {
println it.name // << the artifact name
println it.file // << the file reference
}
It comes from How to retrieve a list of actual dependencies (including transitive deps) - Old Forum - Gradle Forums

I'm just a gradle newbie, so perhaps there is depth to your question I don't see. Do you mean:
> gradle dependencies
:dependencies
------------------------------------------------------------
Root project
------------------------------------------------------------
archives - Configuration for archive artifacts.
No dependencies
compile - Compile classpath for source set 'main'.
\--- commons-collections:commons-collections:3.2
default - Configuration for default artifacts.
\--- commons-collections:commons-collections:3.2
runtime - Runtime classpath for source set 'main'.
\--- commons-collections:commons-collections:3.2
testCompile - Compile classpath for source set 'test'.
+--- commons-collections:commons-collections:3.2
\--- junit:junit:4.+ -> 4.12
\--- org.hamcrest:hamcrest-core:1.3
testRuntime - Runtime classpath for source set 'test'.
+--- commons-collections:commons-collections:3.2
\--- junit:junit:4.+ -> 4.12
\--- org.hamcrest:hamcrest-core:1.3
BUILD SUCCESSFUL
Total time: 4.47 secs
This was created from a build.gradle file with only these direct dependencies:
dependencies {
compile group: 'commons-collections', name: 'commons-collections', version: '3.2'
testCompile group: 'junit', name: 'junit', version: '4.+'
}

Related

Combine resolutionStrategy with exclusion

I am using Gradle 6.5.1. I have added a custom resolutionStrategy to a build.gradle file - but now an exclusion like this is not being applied:
testImplementation("com.example:foo-bar_2.12:$dependencies_version"){
exclude group: 'org.scala-lang', module: 'scala-library'
exclude group: 'org.typelevel', module: 'cats-core_2.12' // <- !! NOT WORKING !!
}
So it seems that custom resolutionStrategies and exclusions are not composable, at least not by default, in Gradle 6.5.1. Is there some way I can make Gradle fall back to its "default" resolutionStrategy if mine is not relevant? If not, what should I do?
Issue
You have to have some special resolutionStrategy in place in order to overwrite the exclusion for cats-core_2.12.
Or
Dependency on cats-core_2.12 is being resolved as transitive dependency from other dependency and not com.example:foo-bar_2.12 as you expect. You should use gradle dependency command and post here the result of where cats-core is being resolved.
Example
I have following simple build.gradle build script with similar exclusion rule and resolutionStrategy as you can see below and cats-core will still be excluded from dependencies as expected
dependencies {
testImplementation('com.github.julien-truffaut:monocle-core_2.13:3.0.0-M5'){
exclude group: 'org.scala-lang', module: 'scala-library'
exclude group: 'org.typelevel', module: 'cats-core_2.13' // <- WORKS
}
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.7.0'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.7.0'
}
configurations.all {
resolutionStrategy {
failOnVersionConflict()
preferProjectModules()
force 'org.typelevel:cats-core_2.13:2.4.0'
// cache dynamic versions for 10 minutes
cacheDynamicVersionsFor 10*60, 'seconds'
// don't cache changing modules at all
cacheChangingModulesFor 0, 'seconds'
}
}
Dependencies:
Running following command ./gradlew dependencies
You can see that cats-core is not listed in dependencies as it's excluded.
...
testRuntimeClasspath - Runtime classpath of source set 'test'.
+--- com.github.julien-truffaut:monocle-core_2.13:3.0.0-M5
| \--- org.typelevel:cats-free_2.13:2.6.0
| \--- org.typelevel:simulacrum-scalafix-annotations_2.13:0.5.4
+--- org.junit.jupiter:junit-jupiter-api:5.7.0
| +--- org.junit:junit-bom:5.7.0
| | +--- org.junit.jupiter:junit-jupiter-api:5.7.0 (c)
...
Alternative
If exclusion in your case is not forking for specific dependency, maybe exclusion for all configurations might help like example below:
configurations {
all.collect { configuration ->
configuration.exclude group: 'org.typelevel', module: 'cats-core_2.13'
}
}

Enforce the highest version from among several conflicting transitive dependencies in gradle

I work on a large project with multiple services and libraries, mostly in grails, with gradle builder. I'm trying to update a library (say logback) for security reasons.
I already updated it in one of our libraries (say our-logger), like so:
#our-logger/build.gradle
...
dependencies {
...
compile 'ch.qos.logback:logback-classic:1.2.3'
...
}
when I update a service (say our-service) to use the new version of our-logger i get logback included from other libraries, and gradle chooses the lower version coming through cobertura and some other dependencies, instead of the higher version coming through our-logger.
#our-service/build.gradle
...
apply plugin: 'cobertura'
...
dependencies {
...
compile 'our-logger:9.99' # safe now with logback-1.2.3
...
}
~/our-service $ ./gradlew dependencies
...
cobertura
\--- net.sourceforge.cobertura:cobertura:2.1.1
+--- ch.qos.logback:logback-classic:1.0.13 -> 1.1.11
| \--- ch.qos.logback:logback-core:1.1.11
...
compile - Dependencies for source set 'main' (deprecated, use 'implementation ' instead).
+--- org.grails:grails-dependencies:3.3.8
| +--- org.springframework.boot:spring-boot-starter-logging:1.4.2.RELEASE -> 1.5.15.RELEASE
| | +--- ch.qos.logback:logback-classic:1.1.11
| | | +--- ch.qos.logback:logback-core:1.1.11
...
+--- our-logger:9.99
| +--- ch.qos.logback:logback-classic:1.2.3 -> 1.1.11 (*)
How do I enforce logback-1.2.3 without explicitly declaring it in all services?
The gradle docs file this under Advanced Dependency Management. You should be able to satisfy your goal using excludes. There are other ways too Gradle Docs
compile(“some:other:dependency”) {
exclude group: 'ch.qos.logback', module: 'logback-classic'
}

Why the "dependencies" command returns some "FAILED" results for an empty project with just one dependency, JUnit?

I have a build.gradle like this:
apply plugin: 'java'
dependencies{
compile 'junit:junit:4.12'
}
and when I run gradle dependencies I get:
------------------------------------------------------------
Root project
------------------------------------------------------------
apiElements - API elements for main. (n)
No dependencies
archives - Configuration for archive artifacts.
No dependencies
compile - Dependencies for source set 'main' (deprecated, use 'implementation ' instead).
\--- junit:junit:4.12 FAILED
compileClasspath - Compile classpath for source set 'main'.
\--- junit:junit:4.12 FAILED
compileOnly - Compile only dependencies for source set 'main'.
No dependencies
default - Configuration for default artifacts.
\--- junit:junit:4.12 FAILED
implementation - Implementation only dependencies for source set 'main'. (n)
No dependencies
runtime - Runtime dependencies for source set 'main' (deprecated, use 'runtimeOnly ' instead).
\--- junit:junit:4.12 FAILED
runtimeClasspath - Runtime classpath of source set 'main'.
\--- junit:junit:4.12 FAILED
runtimeElements - Elements of runtime for main. (n)
No dependencies
runtimeOnly - Runtime only dependencies for source set 'main'. (n)
No dependencies
testCompile - Dependencies for source set 'test' (deprecated, use 'testImplementation ' instead).
\--- junit:junit:4.12 FAILED
testCompileClasspath - Compile classpath for source set 'test'.
\--- junit:junit:4.12 FAILED
testCompileOnly - Compile only dependencies for source set 'test'.
No dependencies
testImplementation - Implementation only dependencies for source set 'test'. (n)
No dependencies
testRuntime - Runtime dependencies for source set 'test' (deprecated, use 'testRuntimeOnly ' instead).
\--- junit:junit:4.12 FAILED
testRuntimeClasspath - Runtime classpath of source set 'test'.
\--- junit:junit:4.12 FAILED
testRuntimeOnly - Runtime only dependencies for source set 'test'. (n)
No dependencies
Why are there the FAILED dependencies?
And what does deprecated, use 'implementation' instead mean?
I also used:
testImplementation 'junit:junit:4.12'
but the same command returns still FAILED part: testCompileClasspath and testRuntimeClasspath.
Why is this happening?
If you haven't defined a repositories block gradle will print the dependency and marked it as FAILED, since it hasn't been resolved correctly (there was no placed defined from where the dependency could have been fetched).
When it comes to compile vs implementation have a look here please.

Gradle - unable to track down transitive dependency

I have two modules: common and domain. Domain is a dependency of common. In domain, I'm trying to add the latest version of Spring Data Elasticsearch but it keeps reverting back to an old version. My domain's build.gradle file looks like this:
domain build.gradle
apply plugin: 'spring-boot'
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:1.3.3.RELEASE")
}
}
dependencies {
compile("org.springframework.boot:spring-boot-starter-data-jpa")
compile("org.springframework.boot:spring-boot-starter-redis")
compile("org.springframework.data:spring-data-elasticsearch:2.0.1.RELEASE")
compile 'org.slf4j:slf4j-api'
compile 'com.google.guava:guava:19.0'
compile 'com.google.code.gson:gson:2.4'
testCompile "org.mockito:mockito-core:1.+"
}
The version for elasticsearch here is 2.0.1.RELASE However, if I run dependencyInsight in common, it is retrieving 1.3.4.RELEASE instead:
gradle dependencyInsight --dependency elasticsearch --configuration compile
:common:dependencyInsight
Download https://repo1.maven.org/maven2/org/springframework/data/spring-data-elasticsearch/1.3.4.RELEASE/spring-data-elasticsearch-1.3.4.RELEASE.pom
org.elasticsearch:elasticsearch:1.5.2 (selected by rule)
\--- org.springframework.data:spring-data-elasticsearch:1.3.4.RELEASE
\--- project :domain
\--- compile
org.springframework.data:spring-data-elasticsearch:1.3.4.RELEASE (selected by rule)
org.springframework.data:spring-data-elasticsearch:2.0.1.RELEASE -> 1.3.4.RELEASE
\--- project :domain
\--- compile
common build.gradle
apply plugin: 'spring-boot'
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:1.3.3.RELEASE")
}
}
dependencies {
compile project(':domain')
compile 'com.google.code.gson:gson:2.4'
compile 'org.owasp.encoder:encoder:1.2'
compile 'com.ning:async-http-client:1.9.31'
compile 'org.slf4j:slf4j-api'
compile 'org.springframework.security:spring-security-core'
compile 'org.springframework.security:spring-security-acl:4.0.3.RELEASE'
compile 'javax.mail:javax.mail-api:1.5.4'
compile 'com.sun.mail:javax.mail:1.5.4'
testCompile group: 'junit', name: 'junit', version: '4.12'
testCompile "org.mockito:mockito-core:1.+"
}
Is there a reason why version 1.3.4.RELEASE is replacing 2.0.1.RELEASE?
You're applying Spring Boot's Gradle plugin to your common project. That means that its dependency management will be controlling the versions of the project's dependencies. To get the version of Spring Data Elasticsearch that you want, you can override Boot's dependency management by adding the following:
dependencyManagement {
dependencies {
dependency 'org.springframework.data:spring-data-elasticsearch:2.0.1.RELEASE'
}
}

Gradle dependency - com.google.auto:auto-common:1.0-SNAPSHOT

How do I get com.google.auto:auto-common:1.0-SNAPSHOT (transitive dependency) to resolve, in my gradle build?
build.gradle:
apply plugin: 'java'
repositories {
maven {
mavenLocal()
mavenCentral()
url "http://snapshots.maven.codehaus.org/maven2"
url "http://oss.sonatype.org/content/groups/public"
url "http://nativelibs4java.sourceforge.net/maven"
url "http://repository.jboss.org/"
}
}
dependencies {
compile 'com.google.dagger:dagger:2.0-SNAPSHOT'
compile 'com.google.dagger:dagger-compiler:2.0-SNAPSHOT'
compile 'com.google.guava:guava:18.0'
compile 'com.google.protobuf:protobuf-java:2.6.1'
compile 'com.nativelibs4java:javacl:1.0-SNAPSHOT'
compile 'org.jogamp.gluegen:gluegen-rt-main:2.0.2'
compile 'org.jogamp.jogl:jogl-all-main:2.0.2'
testCompile 'junit:junit:4.12'
testCompile 'org.mockito:mockito-core:1.9.5'
testCompile 'com.google.truth:truth:0.25'
}
Results:
$ gradle build
:compileJava
FAILURE: Build failed with an exception.
* What went wrong:
Could not resolve all dependencies for configuration ':compile'.
> Artifact 'com.google.auto:auto-common:1.0-SNAPSHOT#jar' not found.
* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.
BUILD FAILED
Dependency Tree: (truncated)
$ gradle dependencies
compile - Classpath for compiling the main sources.
+--- com.google.dagger:dagger:2.0-SNAPSHOT
| \--- javax.inject:javax.inject:1
+--- com.google.dagger:dagger-compiler:2.0-SNAPSHOT
| +--- com.google.dagger:dagger:2.0-SNAPSHOT (*)
| +--- com.google.dagger:dagger-producers:2.0-SNAPSHOT
| | +--- com.google.dagger:dagger:2.0-SNAPSHOT (*)
| | \--- com.google.guava:guava:18.0
| +--- com.google.auto:auto-common:1.0-SNAPSHOT <-------auto-common--------
| | \--- com.google.guava:guava:18.0
| \--- com.google.guava:guava:18.0
+--- com.google.guava:guava:18.0
+--- com.google.protobuf:protobuf-java:2.6.1
+--- com.nativelibs4java:javacl:1.0-SNAPSHOT
| \--- com.nativelibs4java:javacl-core:1.0-SNAPSHOT
| +--- com.nativelibs4java:opencl4java:1.0-SNAPSHOT
| | \--- com.nativelibs4java:bridj:0.7-SNAPSHOT
| | \--- com.google.android.tools:dx:1.7
| \--- com.nativelibs4java:nativelibs4java-utils:1.6-SNAPSHOT
+--- org.jogamp.gluegen:gluegen-rt-main:2.0.2
| \--- org.jogamp.gluegen:gluegen-rt:2.0.2
\--- org.jogamp.jogl:jogl-all-main:2.0.2
\--- org.jogamp.jogl:jogl-all:2.0.2
I have tried adding an explicit dependency for auto-common, with no luck.
To my surprise, searching things like "com.google.auto:auto-common:1.0-SNAPSHOT repository" turns up very little. It looks like the 1.0-SNAPSHOT simply isn't in Maven Central. Interestingly enough, it looks like the 1.0-SNAPSHOT is in jboss's repository, but my gradle build doesn't seem to find it.
Anyone seen something like this before? Help?
It will work in the following way - every maven url should be specified in a separate maven{} block - run copyToLibs task to verify:
apply plugin: 'java'
repositories {
mavenLocal()
mavenCentral()
[
"http://snapshots.maven.codehaus.org/maven2",
"http://oss.sonatype.org/content/groups/public",
"http://nativelibs4java.sourceforge.net/maven",
"http://repository.jboss.org/"
].each { address ->
maven {
url address
}
}
}
dependencies {
compile 'com.google.dagger:dagger:2.0-SNAPSHOT'
compile 'com.google.dagger:dagger-compiler:2.0-SNAPSHOT'
compile 'com.google.guava:guava:18.0'
compile 'com.google.protobuf:protobuf-java:2.6.1'
compile 'com.nativelibs4java:javacl:1.0-SNAPSHOT'
compile 'org.jogamp.gluegen:gluegen-rt-main:2.0.2'
compile 'org.jogamp.jogl:jogl-all-main:2.0.2'
testCompile 'junit:junit:4.12'
testCompile 'org.mockito:mockito-core:1.9.5'
testCompile 'com.google.truth:truth:0.25'
}
task copyToLib(type: Copy) {
from configurations.runtime
into 'libs'
}
In the way You specified the urls the last one was winning (covering all previously defined).

Resources