I've recently run into a situation where I have a conflict because my Gradle dependency resolve results in 2 different-name jar files that are actually having the same contents. It's taken me a while to determine which dependency declaration a jar is from so I can exclude one of them. Is there an easy way that can allow gradle to generate some kind of report so that I can see which jars a dependency is resolved to?
Thanks!
You could use something like the following task which will list out all the files brought in by each of your dependencies.
task dependencyFiles << {
configurations.compile.dependencies.all {
println "${it}: "
println configurations.compile.files(it).collect { it.name }
}
}
Yes, there is. The project report plugin is what you're looking for, especially the dependencyReport and htmlDependencyReport tasks it adds to the project, as well as the dependencyInsight command it allows to execute to get information about a specific dependency.
Related
I have a Gradle build in which I am publishing the output to the Maven local repo (its used by other modules of a larger non Gradle build). But doing so generates this warning:
Gradle detected a problem with the following location:
'display\build\outputs\apk\release\display-release.apk'. Reason: Task
':display:publishMavenAndroidPublicationToMavenLocal' uses this output
of task ':display:packageRelease' without declaring an explicit or
implicit dependency. This can lead to incorrect results being
produced, depending on what order the tasks are executed. Please refer
to
https://docs.gradle.org/7.2/userguide/validation_problems.html#implicit_dependency
for more details about this problem.
The link suggests that I declare a dependency between the 2 tasks.
But neither of the tasks are custom tasks, they are part of the included plugins. And I despite spending hours trying all kinds of syntax I can't work out how to declare the dependency from the publishToMavenLocal to the package task.
How do I declare it?
plugins {
id 'com.android.application'
id 'maven-publish' // So that we can publish the APKs
}
android {
...
}
publishing {
publications {
mavenAndroid(MavenPublication) {
groupId = 'com.mygroup.foo'
artifactId = project.name
version = 1.2.3'
artifact "$buildDir/outputs/apk/release/${project.name}-release.apk"
// Explicitly not generating a pom dependencies node
// 1) we don't need it because the APK includes all its deps.
on Artifactory.
}
}
}
build.finalizedBy publishToMavenLocal
I believe the problem stems from this line:
artifact "$buildDir/outputs/apk/release/${project.name}-release.apk"
The APK at that location is created by some task. Instead of referencing that tasks' output, you have given a direct path. Because of that, Gradle is not able to accurately deduce task dependencies.
I am not an Android developer, but judging from the error:
uses this output of task ':display:packageRelease' without declaring an explicit or implicit dependency.
The project display has a task named packageRelease which may or may not come from the Android Gradle plugin. Again, I am not an Android developer, so do not know for certain. The packageRelease is what produces the APK at the aforementioned path.
The publishMavenAndroidPublicationToMavenLocal is created when you create a publication named mavenAndroid; this is documented in the maven-publish documentation
With that said, you must declare task dependencies between the two. Something like:
tasks.withType(PublishToMavenRepository::class).configureEach {
inputFile.from(packageRelease)
}
tasks.withType(PublishToMavenLocal::class).configureEach {
inputFile.from(packageRelease)
}
Without knowing the task type of packageRelease and unfamiliarity with Android projects, best I can do above.
In a Gradle project I have multiple sub-projects. I need to copy the dependencies from the configuration of one sub-project to that of another. I can achieve this using the following, adapted from this answer here:
task copyDependencies(type: Copy) {
from project(":sub").configurations.compile
into "${buildDir}/libraries"
}
Unfortunately, with Gradle 5.1, this generates the following deprecation warning (truncated for brevity):
The configuration :sub:compile was resolved without accessing the project in a safe manner. ... This behaviour has been deprecated and is scheduled to be removed in Gradle 6.0.
What's the best way to do this now for Gradle 5.1 and later?
The warning appeared as reaching across project boundaries can cause issues when the build runs in parallel.
The proper way of doing this is to let Gradle know that the project declaring the copyDependencies task will need the project :sub's dependencies.
You can achieve this by doing the following:
configurations {
dependenciesToCopy
}
dependencies {
dependenciesToCopy project(':sub')
}
task copyDependencies(type: Copy) {
from configurations.dependenciesToCopy
into "${buildDir}/libraries"
}
This will cause Gradle to properly create an execution dependency between your project and the resolution of the dependencies of the sub project.
Relevant discussion on the Gradle forums.
Objective: Create Jar of Jars like Maven does.
I have this relevant snippet:
jar {
into('lib') {
from configurations.compile, configurations.runtime
}
}
There must be something wrong with my conceptualization of what compile / runtime are. If I do this, I get duplicate copies of every library in the resulting jar. I'm really only trying to include everything that might go in and cover all the scopes. I want something I can easily rubber stamp for most jar situations as this is a very large build. I can get more specific for war files.
So... Why does this happen?
The gradle documentation says this about the runtime configuration:
"runtime: The dependencies required by the production classes at runtime. By default, also includes the compile time dependencies."
Just by copying from the runtime configuration, you would get all of the compile dependencies aswell. You are basically telling gradle to copy the same dependencies twice.
gradle multiple build script dependencies
We am in the process from transacting my our build scripts from ant to gradle. The ant build is configured the old way without using ivy and getting the dependencies from a lib folder.
We have a number of custom ant tasks packaged in jar. To run the tasks in that jar we also need some other third parties dependencies from the same lib folder.
Being a complex build we cannot afford to move everything in one go and would rather move one bit at a time as we find some time to do it.
I was able to run those custom ant tasks from the gradle build but I am having problems accessing classes from or tasks jars in my gradle build scripts.
In the build script section we have a class path entry needed for artifactory plugin and I tried to add some more class path entries to make our local libs available.
buildscript {
….
dependencies {
// This dependency below is needed by artifactory plugin which we download
classpath "org.jfrog.buildinfo:build-info-extractor-gradle:3.0.1"
}
….
}
I tried lots of combinations but I could not get it to work. What we want is to be able to do something like below:
buildscript {
…
dependencies {
classpath {
["org.jfrog.buildinfo:build-info-extractor-gradle:3.0.1",
fileset(dir: "${antBuildDir}/customTasks", includes: 'myTasks.jar'),
fileset(dir: "${antBuildDir}/lib", includes: '*.jar')]
}
}
…
}
Any idea about how can I address this or any other suggestions if you think I am on the wrong path.
Thank you in advance.
Julian
I can get a list of dependencies with gradlew dependencies --configuration runtime. Is there a command-line way to have it emit the file system paths of the dependencies in the Gradle cache?
Alternatively, what I really want to output is a usable classpath generated from the dependencies. Is there a way to get that from the dependencies command? Something like what the following outputs but without having to go through the motions of creating a task:
task classpath << {
println configurations.runtime.asPath
}
If you want to output a class path, a task like the above is the best solution. Note that the Gradle dependency cache is an internal data structure and you shouldn't make any assumptions about its layout (which may change between versions).