I am using Gradle 6.1 in a multimodule project. I am also using two plugins: kotlin("jvm") and id("com.google.cloud.tools.jib"), and they are loaded in the following modules:
root/
build.gradle.kts loads kotlin("jvm")
services/
my-service/
rest/
build.gradle.kts loads id("com.google.cloud.tools.jib")
(There are more modules, files etc. but these are the relevant ones.)
The build fails:
$ ./gradlew clean jibDockerBuild
...
* What went wrong:
Execution failed for task ':services:driver:rest:jibDockerBuild'.
> com.google.cloud.tools.jib.plugins.common.BuildStepsExecutionException: 'org.apache.http.client.config.RequestConfig$Builder
org.apache.http.client.config.RequestConfig$Builder.setNormalizeUri(boolean)'
I identified the issue: both the Kotlin and JIB plugins have a transitive dependency on org.apache.httpcomponents:httpclient: Kotlin requires 4.5.3 and JIB 4.5.10. The problem is, in this project setup only 4.5.3 is loaded, and JIB fails as the new method is not available. This can be checked with ./gradlew buildEnv.
I've found a workaround, I need to load both plugins at the root level (which one is first seems to be irrelevant) in the main Gradle file; now ./gradlew buildEnv shows that the higher dependency version is used, also for Kotlin (output shortened and incomplete):
classpath
+--- org.jetbrains.kotlin.jvm:org.jetbrains.kotlin.jvm.gradle.plugin:1.3.61
| \--- org.jetbrains.kotlin:kotlin-gradle-plugin:1.3.61
| +--- de.undercouch:gradle-download-task:3.4.3
| | \--- org.apache.httpcomponents:httpclient:4.5.3 -> 4.5.10
It works in this case, but it could be that the new library version breaks the Kotlin plugin. The problem is that the plugins and their dependencies are on the classpath without separation, something that was normal on Java before Jigsaw etc. Is there any way for Gradle to be able to separate the dependencies so that each plugin uses exactly the version it declares? I am building on Java 11, so the module system could be utilized, but does Gradle have an option to turn it on?
EDIT: updating to Kotlin 1.3.70 also fixes the issue as it doesn't depend on the library any longer. The general question is still valid, though.
Is there any way for Gradle to be able to separate the dependencies so that each plugin uses exactly the version it declares
No.
All plugins share the same build script configuration: classpath
It follows the same dependency resolution that application dependencies follow. So you can enforce that for this particular dependency only use a specific version always:
buildscript {
configurations {
classpath {
resolutionStrategy {
force("org.apache.httpcomponents:httpclient:4.5.10")
}
}
}
}
That's just one of many ways you can take control of dependency resolution for build script dependencies. You could also use a platform to advise on the dependency versions:
buildscript {
dependencies {
classpath(enforcedPlatform("org.springframework.boot:spring-boot-dependencies:2.2.5.RELEASE"))
}
}
Refer to the docs for more info:
https://docs.gradle.org/current/userguide/resolution_rules.html
https://docs.gradle.org/current/userguide/platforms.html
I am using the Spring Boot Gradle plugin and its dependency management to manage some of my own dependencies across project so I do not need to add an explicit version in the build.gradle.
dependencyManagement {
dependencies {
dependency "foo.bar:my-own-library:12.1"
}
}
The problem is that I need another version "11.9" beside the version "12.1" and that I wanted the plugin to pick the correct version based on a variable.
So I added a resolutioStrategy and some variables in ext:
dependencyManagement {
dependencies {
dependency "foo.bar:our-own-library:12.1"
}
resolutionStrategy {
eachDependency { details ->
//find available version based on src_compat
//set the new version to use via
details.useVersion(newVersion)
// details.target.version yields updated version
}
}
}
ext {
src_compat = 11
extra_versions = ["foo.bar:my-own-library" : ["11.9"]]
}
The target version is set correctly every time but than the old version (12.1) is used for every configuration.
The configurations have no other custom resolutionstrategy.
My assumption was the resolutionStrategy of the plugin is able to override every version when the dependency management of the plugin is used.
Is the resolutionStrategy able to override all versions or do I have to move it the 'normal' gradle configurations?
There's some information about this in the dependency management plugin's documentation.
The dependency management resolution strategy only applies to the plugin's internal configurations, such as those that it uses to resolve the Maven boms that you have imported. As you suspected, if you want the resolution strategy to apply to the resolution of your project's dependencies, you should move it to the normal Gradle configurations.
I have a fresh install of IntelliJ, I created a new kotlin gradle project using the following settings:
This produces the following build.gradle.kts, (the exact same file works on my Windows machine):
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins {
kotlin("jvm") version "1.2.71"
}
group = "com.test"
version = "1.0-SNAPSHOT"
repositories {
mavenCentral()
}
dependencies {
compile(kotlin("stdlib-jdk8"))
}
tasks.withType<KotlinCompile> {
kotlinOptions.jvmTarget = "1.8"
}
Which produces this error, when trying to do a gradle refresh:
Plugin [id: 'org.jetbrains.kotlin.jvm', version: '1.2.71'] was not
found in any of the following sources:
Gradle Core Plugins (plugin is not in 'org.gradle' namespace)
Plugin Repositories (could not resolve plugin artifact 'org.jetbrains.kotlin.jvm:org.jetbrains.kotlin.jvm.gradle.plugin:1.2.71')
Searched in the following repositories:
Gradle Central Plugin Repository
Check your Internet connection and make sure your Internet is not restricted.
I solved this problem by turning on proxy for all tunnels (not just HTTP) with a VPN app.
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins {
// kotlin("jvm") version "1.2.71"
}
group = "com.test"
version = "1.0-SNAPSHOT"
repositories {
mavenCentral()
}
dependencies {
compile(kotlin("stdlib-jdk8"))
}
//tasks.withType<KotlinCompile> {
// kotlinOptions.jvmTarget = "1.8"
//}
gradle sync by commenting the above lines. The gradle will be set up.
once the gradle is downloaded, uncomment those line and sync again.
if the dependencies are not downloaded properly, run 'gradle build' in the terminal and click on gradle sync.
This solved the issue for me.
(1) in my case (OpenJDK 11 on Ubuntu 18.04) the problem was Gradle not being able to download the POM file from gradle plugin-server. you can test it by entering this line into jshell:
new java.net.URL("https://plugins.gradle.org/m2/org/jetbrains/kotlin/jvm/org.jetbrains.kotlin.jvm.gradle.plugin/1.3.11/org.jetbrains.kotlin.jvm.gradle.plugin-1.3.11.pom").openStream()
(you can find your url by running gradle with --debug option)
So if you received an exception like this: InvalidAlgorithmParameterException: trustAnchors parameter must be non-empty then the trouble is CA-certs cache. which could be easily fixed by writing these lines into bash Ref:
sudo su
/usr/bin/printf '\xfe\xed\xfe\xed\x00\x00\x00\x02\x00\x00\x00\x00\xe2\x68\x6e\x45\xfb\x43\xdf\xa4\xd9\x92\xdd\x41\xce\xb6\xb2\x1c\x63\x30\xd7\x92' > /etc/ssl/certs/java/cacerts
/var/lib/dpkg/info/ca-certificates-java.postinst configure
By the way do not forget to restart gradle daemon before trying again. (gradle --stop)
(2) another reason could be your internet not having access to bintray.com (the internet of Iran or China) which you can test by putting this line on jshell :
new java.net.URL("https://jcenter.bintray.com/org/jetbrains/kotlin/kotlin-gradle-plugin-api/1.3.11/kotlin-gradle-plugin-api-1.3.11.pom").openStream()
If you received a connection timeout, it confirms this theory. In this case you need to buy and have proxy/vpn connected in order to be able to download these dependencies.
Check your gradle and kotlin (or Java) versions.
I got the same error and my issue is solved by specifying the kotlin version in build.gradle:
Before:
plugins {
id 'org.jetbrains.kotlin.jvm'
}
After:
plugins {
id 'org.jetbrains.kotlin.jvm' version "1.4.10"
}
In my case (Ubuntu 20.04), problem was with gradle 7.2, installed from snap.
I have removed gradle 7.2, installed from snap and install gradle 7.2 from sdkman. Works fine for me.
If you are using java like me .I got the issue fixed by adding the following:
Root gradle
dependencies {
ext.kotlin_version = '1.4.10'
classpath "com.android.tools.build:gradle:7.0.4"
classpath "com.google.dagger:hilt-android-gradle-plugin:2.38.1"
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
......
}
App gradle file
plugins {
id 'com.android.application'
id 'kotlin-android'
id 'kotlin-kapt'
id 'dagger.hilt.android.plugin'
}
dependencies {
implementation "com.google.dagger:hilt-android:2.38.1"
kapt "com.google.dagger:hilt-compiler:2.38.1"
......
}
Ok, so the answer was very simple all along. For some reason I activated gradle's "Offline work" toggle and that was the cause of the problem.
To disable it simply go to Settings > Build, Execution, Deployment > Build Tools > Gradle and deselect the "Offline work" checkbox.
In my case the problem was because Charles Proxy. After closing Charles I could start working again
I updated my Kotlin version to 1.7.20 and fixed this problem.
id 'org.jetbrains.kotlin.android' version '1.7.20' apply false
I recently had similar issue with an empty project autogenerated by Intellij Idea.
Solved this problem by combining Java and Gradle versions.
Initially I had Oracle Java 8 with Gradle 6.8.3.
After several attempts I found a working combination - AdoptOpenJDK 11 and Gradle 5.6.4
In my case I changes the Gradle JVM in Settings > Build, Execution, Deployment > Build Tools > Gradle and it worked.
Disconnect from your VPN (or make sure you have an open internet connection), then restart Android Studio.
If you don't restart it sometimes it continues with invalid proxy properties.
This for Ktor devs. If you are working on a ktor application with the web project generator there is a chance the generator sets invalid jvm plugin version. So make sure you are setting correct version for jvm plugin. You can find the latest jvm plugin version here. Here is the sample build.gradle.kts file.
//Plugin section
plugins {
kotlin("jvm") version "1.8.0"
id("io.ktor.plugin") version "2.2.2"
}
//Dependancy section
dependencies {
...
testImplementation("io.ktor:ktor-server-tests-jvm:1.8.0")
testImplementation("org.jetbrains.kotlin:kotlin-test-junit:1.8.0")
...
}
I want to share my problem with you. Maybe somebody faced this problem also and will have solution.
In brief Gradle doesn't resolve frequently changing dependencies.
We're using:
./gradlew -v
------------------------------------------------------------
Gradle 2.12
------------------------------------------------------------
Build time: 2016-03-14 08:32:03 UTC
Build number: none
Revision: b29fbb64ad6b068cb3f05f7e40dc670472129bc0
Groovy: 2.4.4
Ant: Apache Ant(TM) version 1.9.3 compiled on December 23 2013
JVM: 1.8.0_66 (Oracle Corporation 25.66-b17)
OS: Linux 2.6.18-409.el5 amd64
Let me try to explain what's happened.
We have some project that have dependency of another independent project.
Both are under active development.
One is: string-parser version: 1.0.0-SNAPSHOT
Second is: tools-utils version: 2.2.0-SNAPSHOT
We have internal maven artifactory and we configured it in string-parser:
# some code there
configurations.all {
resolutionStrategy.cacheChangingModulesFor 0, TimeUnit.MILLISECONDS
}
repositories {
mavenLocal()
maven { url 'https://some.internal.com/deploy-snapshot'}
maven { url 'https://some.internal.com/deploy-release'}
}
dependencies {
# Some other dependencies listed here
compile('com.some.group:tools-utils:2.2.0-SNAPSHOT') {
changing = true
}
}
So when we're doing changes at local work station (Windows - I think it doesn't matter) for tools-utils and upload last snapshot artifact version to maven local and remote everything is okay. We go to string-parser project press "reimport" button (in Intellij Idea 2016.1.2) and Gradle switch to correct dependency version.
But if somebody does some changes and upload new version to Maven remote it won't update dependency in cache and still point to old version. To fix it we have manually delete artifact from Gradle cache and (!) from Maven Local.
Could you please advice me something because cleaning up cache manually (or with addition step on TeamCity) is a nightmare?
Try putting this in allprojects
// forces all changing dependencies (i.e. SNAPSHOTs) to automagicially download
// (thanks, #BillBarnhill!)
configurations.all {
resolutionStrategy {
cacheChangingModulesFor 0, 'seconds'
}
}
Source: Gradle-Fury
We have a custom gradle plugin, which is applied to all the projects we have. Since the plugin is released every several days, I don't want to update all the codebase to change it to use the latest version of the plugin.
How to declare it in gradle to ask it always get the latest version of the dependency?
I tried:
dependencies {
classpath "com:my-plugin:[1.0.0,)"
}
or
dependencies {
classpath "com:my-plugin:+"
}
They can get the latest version the first time, but won't get the newer one again.
as a default, once gradle resolved a dynamic dependency, gradle won't check for newer versions for 24h. you have different options to influence this. one option is to run your build with --refresh-dependencies or you customize the TTL in your build script. E.g:
configurations.all {
resolutionStrategy.cacheDynamicVersionsFor 10, 'minutes'
}
The following script should do the job:
apply plugin: 'java'
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'com.google.inject:guice:latest.release'
}
}
Check out the docs here.
Another option is to go for snapshot publishing and configure dependency resolver to check seconds if the library changes so often.