I am using the kotlin-gradle-plugin, configuring it as follows in build.gradle:
buildscript {
ext {
springBootVersion = '2.1.2.RELEASE'
kotlinVersion = '1.3.11'
}
repositories {
mavenLocal()
mavenCentral()
maven { url "http://repo.spring.io/plugins-release" }
maven { url "https://plugins.gradle.org/m2/" }
}
dependencies {
classpath "org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}"
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:${kotlinVersion}"
classpath "org.jetbrains.kotlin:kotlin-allopen:${kotlinVersion}"
}
apply plugin: 'kotlin'
apply plugin: 'kotlin-spring'
When I run gradle dependencies I get the following kotlinCompilerClasspath among other things:
kotlinCompilerClasspath
\--- org.jetbrains.kotlin:kotlin-compiler-embeddable:1.3.11
+--- org.jetbrains.kotlin:kotlin-stdlib:1.3.11
| +--- org.jetbrains.kotlin:kotlin-stdlib-common:1.3.11
| \--- org.jetbrains:annotations:13.0
+--- org.jetbrains.kotlin:kotlin-script-runtime:1.3.11
\--- org.jetbrains.kotlin:kotlin-reflect:1.3.11
\--- org.jetbrains.kotlin:kotlin-stdlib:1.3.11 (*)
When I disabled transitive dependencies in my build.gradle as follows:
configurations {
all {
transitive = false
resolutionStrategy {
// fail eagerly on version conflict (includes transitive dependencies)
// e.g. multiple different versions of the same dependency (group and name are equal)
failOnVersionConflict()
}
}
}
Now when I run gradle dependencies I get the following kotlinCompilerClasspath
kotlinCompilerClasspath
\--- org.jetbrains.kotlin:kotlin-compiler-embeddable:1.3.11
How can I add dependencies to the above kotlinCompilerClasspath while still using transitive = false configuration?
For example, I have tried adding the dependency org.jetbrains.kotlin:kotlin-stdlib to the regular dependencies block and to the buildscript block but still the above kotlinCompilerClasspath does not change.
Gradle version
gradle --version
------------------------------------------------------------
Gradle 5.1.1
------------------------------------------------------------
Build time: 2019-01-10 23:05:02 UTC
Revision: 3c9abb645fb83932c44e8610642393ad62116807
Kotlin DSL: 1.1.1
Kotlin: 1.3.11
Groovy: 2.5.4
Ant: Apache Ant(TM) version 1.9.13 compiled on July 10 2018
JVM: 1.8.0_191 (Oracle Corporation 25.191-b12)
OS: Mac OS X 10.14.2 x86_64
UPDATE
As recommended by hotkey below, I filtered out kotlin from the configuration, as follows.
configurations {
matching { !it.name.toLowerCase().contains('kotlin') }.all {
transitive = false
resolutionStrategy {
// fail eagerly on version conflict (includes transitive dependencies)
// e.g. multiple different versions of the same dependency (group and name are equal)
failOnVersionConflict()
}
}
}
I would recommend not to disable transitive dependencies for the kotlinCompilerClasspath configuration in the first place, the Kotlin Gradle plugin expects that configuration to pull the transitive dependencies of the Kotlin compiler as well:
configurations {
matching { it.name != 'kotlinCompilerClasspath' }.all {
transitive = false
/* ... */
}
}
If you still want to disable transitive dependencies for all configurations, you can instead manually add those dependencies which were reported as transitive for the kotlin-compiler-embeddable module:
dependencies {
kotlinCompilerClasspath 'org.jetbrains.kotlin:kotlin-stdlib'
kotlinCompilerClasspath 'org.jetbrains.kotlin:kotlin-script-runtime'
kotlinCompilerClasspath 'org.jetbrains.kotlin:kotlin-reflect'
kotlinCompilerClasspath 'org.jetbrains:annotations:13.0'
}
Related
There's a sample Spring Boot project here that contains two modules.
The build.gradle for one of the modules looks like this:
buildscript {
ext { springBootVersion = '2.1.4.RELEASE' }
repositories { mavenCentral() }
dependencies { classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}") }
}
plugins {
id "io.spring.dependency-management" version "1.0.5.RELEASE"
}
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'
bootJar {
baseName = 'gs-multi-module-application'
version = '0.0.1-SNAPSHOT'
}
sourceCompatibility = 1.8
repositories { mavenCentral() }
dependencies {
compile('org.springframework.boot:spring-boot-starter-actuator')
compile('org.springframework.boot:spring-boot-starter-web')
compile project(':library')
testCompile('org.springframework.boot:spring-boot-starter-test')
}
The other module's build.gradle looks like this:
buildscript {
repositories { mavenCentral() }
}
plugins { id "io.spring.dependency-management" version "1.0.5.RELEASE" }
ext { springBootVersion = '2.1.4.RELEASE' }
apply plugin: 'java'
apply plugin: 'eclipse'
jar {
baseName = 'gs-multi-module-library'
version = '0.0.1-SNAPSHOT'
}
sourceCompatibility = 1.8
repositories { mavenCentral() }
dependencies {
compile('org.springframework.boot:spring-boot-starter')
testCompile('org.springframework.boot:spring-boot-starter-test')
}
dependencyManagement {
imports { mavenBom("org.springframework.boot:spring-boot-dependencies:${springBootVersion}") }
}
The springBootVersion = '2.1.4.RELEASE' is declared in both modules. For a 2 module project that might not be a problem, but if my project had 10 modules and I wanted to make sure that all modules always depend on the same version of Spring Boot, it would be inconvenient and error-prone to repeat this version in every module.
Similarly, I might want to add a dependency on commons-io to both of these modules, and ensure they both always depend on the same version of commons-io.
How can I avoid repeating the version numbers in each and every build.gradle file?
See this Gradle documentation : a good practice in Gradle is to configure subprojects which share common traits in a single place, for example in the root project's build script (or using custom plugins)
EDIT the solution proposed here is no longer considered as good practice from Gradle team (the link above does not even mention subproject bloc in latests Gradle version doc); thank you #buggy for the warning .
In your example taken from Spring boot documentation, this pattern could be applied to centralize Spring boot and other common dependencies versions in a single place, but you could go further and also configure other common traits (Java plugin configuration, repositoties, etc..)
Here is how I would re-write the Spring example to make it cleaner and DRY:
Root project
/**
* Add Springboot plugin into build script classpath (without applying it)
* This is this only place where you need to define the Springboot version.
*
* See https://docs.spring.io/spring-boot/docs/current/gradle-plugin/reference/html/#managing-dependencies-using-in-isolation
*/
plugins {
id "org.springframework.boot" version "2.1.4.RELEASE" apply false
}
// Set version for dependencies share between subprojects
ext {
commonsIoVersion = "2.6"
}
subprojects {
// common config for all Java subprojects
apply plugin: "java"
apply plugin: "eclipse"
sourceCompatibility = 1.8
repositories {
mavenCentral()
}
// apply Spring Boot's dependency management plugin
apply plugin: "io.spring.dependency-management"
}
Library sub-project
// no need for additional plugins
jar {
baseName = 'gs-multi-module-library'
version = '0.0.1-SNAPSHOT'
}
dependencies {
implementation('org.springframework.boot:spring-boot-starter')
implementation "commons-io:commons-io:${commonsIoVersion}"
testCompile('org.springframework.boot:spring-boot-starter-test')
}
dependencyManagement {
imports {
mavenBom org.springframework.boot.gradle.plugin.SpringBootPlugin.BOM_COORDINATES
}
}
Application sub-project
plugins {
id "org.springframework.boot"
}
bootJar {
baseName = 'gs-multi-module-application'
version = '0.0.1-SNAPSHOT'
}
dependencies {
implementation project(':library')
implementation ('org.springframework.boot:spring-boot-starter-actuator')
implementation ('org.springframework.boot:spring-boot-starter-web')
implementation "commons-io:commons-io:${commonsIoVersion}"
// could also be configured in root project.
testCompile('org.springframework.boot:spring-boot-starter-test')
}
Notes
this solution uses the new plugins {} DSL only (no need for old buildscript block)
version of the io.spring.dependency-management should not be configured explicitly, it will be inherit from Spring boot plugin
You can move the ext{} block to a new file and reference it in your project's build.gradle file via the apply from: statement.
// project/versions.gradle
ext {
springBootVersion = '2.1.4.RELEASE'
}
// project/build.gradle
buildscript {
apply from: 'versions.gradle'
}
// module/build.gradle
dependencies {
implementation "some.dependency:dependency:$springBootVersion"
}
Now you only have to define your dependency versions in one place.
Typically, a project will have a project-level build.gradle file in addition to module-specific build.gradle files. However, the repo you shared is missing the project-level build script. This is why the ext{} block is defined in each module's build script. This is likely not optimal, and I recommend looking at other repos to see how different developers tackled this issue.
There's a Gradle consistent versions plugin that will handle this:
https://github.com/palantir/gradle-consistent-versions
After you set this plugin up in the root build.gradle file, you will create a versions.props file like this, to use the example from the documentation.
com.fasterxml.jackson.*:jackson-* = 2.9.6
com.google.guava:guava = 21.0
com.squareup.okhttp3:okhttp = 3.12.0
junit:junit = 4.12
org.assertj:* = 3.10.0
There's also a versions.locks file, which is auto-generated by ./gradlew --write-locks. You can then specify version-less dependencies in your build.gradle files.
I am using eclipse 2018, gradle 5.2.1, buildship 3.0.1.
My config looks like:
I try to create spring boot 2 according to building-spring-boot-2-projects-with-gradle
The build.gradle is:
plugins {
id 'java'
id 'com.gradle.build-scan' version '2.1'
id 'org.springframework.boot' version '2.1.3.RELEASE'
}
repositories {
jCenter()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-dependencies:2.1.3.RELEASE'
implementation 'org.springframework.boot:spring-boot-starter-web'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
components {
withModule('org.springframework:spring-beans') {
allVariants {
withDependencyConstraints {
// Need to patch constraints because snakeyaml is an optional dependency
it.findAll { it.name == 'snakeyaml' }.each { it.version { strictly '1.23' } }
}
}
}
}
}
buildScan {
// always accept the terms of service
termsOfServiceUrl = 'https://gradle.com/terms-of-service'
termsOfServiceAgree = 'yes'
// always publish a build scan
publishAlways()
}
bootJar {
mainClassName = 'gt4.App'
}
However, after I save build.gradle, the Project and External Dependencies disappear, and the spring boot jars are not downloaded too.
What I was wrong?
If I create spring boot project with gradle by Spring Tool Suite 4, the generated build.gradle is:
plugins {
id 'org.springframework.boot' version '2.1.3.RELEASE'
id 'java'
}
apply plugin: 'io.spring.dependency-management'
group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '1.8'
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
then it works.
Do I use spring-boot-dependencies wrong?
try to deleting the local Repository and build project again to download dependancy.
Delete .m2 or .gradle folder and then Rebuild your project.
a)On a Windows machine, the .gradle or .m2 path will be:
c:\Users\username\.m2 or c:\Users\username\.m2
b)On linux machine, the .gradle or .m2 path will be:
USER_HOME/.m2/
I'm trying to make a custom standalone Kotlin plugin for Gradle and am trying to apply that to another project, but am getting a Plugin with id 'my.id.license-tools' not found error when trying to apply it to another project.
This is the structure of the plugin's project:
license-tools
+--src
+--main
| +--java
| |
| +--kotlin
| | +--my.id
| | +--LicenseTools.kt
| |
| +--resources
| +--META-INF.gradle-plugins
| +--my.id.license-tools.properties
+--test
+--build.gradle
This is my build.gradle file:
buildscript {
ext.kotlin_version = '1.2.21'
repositories {
mavenCentral()
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
group 'my.id'
version '0.1'
apply plugin: 'java'
apply plugin: 'kotlin'
apply plugin: 'idea'
apply plugin: 'maven'
sourceCompatibility = 1.8
repositories {
mavenCentral()
}
dependencies {
compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
compile gradleApi()
testCompile group: 'junit', name: 'junit', version: '4.12'
}
compileKotlin {
kotlinOptions.jvmTarget = "1.8"
}
compileTestKotlin {
kotlinOptions.jvmTarget = "1.8"
}
Then we have the Plugin class LicenseTools.kt, which I've held very simple to make sure the error didn't come from there:
package my.id
import org.gradle.api.Plugin
import org.gradle.api.Project
open class LicenseTools: Plugin<Project> {
override fun apply(project: Project?) {
println("License-Tools plugin has been applied")
}
}
And lastly my.id.license-tools.properties:
implementation-class=my.id.LicenseToolsKt
I've also tried
implementation-class=my.id.LicenseTools
After building everything with ./gradlew clean build I've run ./gradlew install to install the whole thing to the local Maven repository, which it did successfully.
Then I went ahead and added the following to my other project's buildscript block:
repositories {
mavenLocal()
mavenCentral()
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath "my.id:license-tools:0.1"
}
And after that added
apply plugin: 'my.id.license-tools'
After trying out many different things, like changing to the new plugins block or making sure the artifacts get correctly installed to the local maven repository I can't find the root of the problem, since according to the many guides I've read through, this should be the correct way to go about making a standalone plugin.
you probably figured by now, but your my.id.license-tools.properties should be named my.id.properties
the content should then be implementation-class=my.id.LicenseTools
then the classpath should be named
classpath "my.id:license-tools:0.1" -> classpath "my.id:LicenseTools:0.1"
and
apply plugin: 'my.id.license-tools' -> apply plugin: 'my.id.LicenseTools'
so that it always is:
package: my.id
name: LicenseTools
I haven't actually tested all of that, though.
I have a mutli module gradle project:
subprojects {
apply plugin: 'java-library'
}
project(':core') {
dependencies {
compile project(':module:mod-a')
}
}
project(':module:mod-a') {
dependencies {
compile project(':core')
}
}
project(':module:mod-b') {
dependencies {
compile project(':core')
}
}
Of course this causes a circular compile dependency:
* What went wrong:
Circular dependency between the following tasks:
:core:compileJava
+--- :core:compileJava (*)
\--- :module:mod-a:compileJava
+--- :core:compileJava (*)
\--- :module:mod-a:compileJava (*)
What bothers me is that even if I change the compile dependency from :core to :module:mod-a to a runtime dependency it still is not possible to compile the project:
* What went wrong:
Circular dependency between the following tasks:
:module:mod-a:compileJava
\--- :module:mod-a:compileJava (*)
I don't see why there is a problem. The :core does need the module only at runtime and therefore can be compiled first. Afterwards the modules can be compiled using the core. Furthermore the :core is not part of the error message from Gradle anymore. So Gradle seems to "see" that it is just a runtime dependency.
Where is the problem and how can it be fixed?
Using runtimeOnly instead of runtime seems to solve the problem.
When you do
dependencies {
runtime project(':xxx')
}
It's the same as
dependencies {
runtime project(path: ':xxx', configuration: 'default')
}
See here which states that the default configuration extends runtime.
So by doing this you are making :module:mod-a depend on the runtime configuration from :core. Hence the curcular dependency
You could probably reference the archives configuration instead of default to break the cycle
eg:
subprojects {
apply plugin: 'java'
}
project(':core') {
artifacts {
archives jar
}
}
project(':module:mod-a') {
dependencies {
compile project(path: ':core', configuration: 'archives')
compile project(path: ':core', configuration: 'runtime')
}
}
in spring-boot web-app,
when i use #PastOrPresent STS shows me this error :
(PastOrPresent cannot be resolved to a type)
but org.springframework.boot:spring-boot-starter-validation entry is already among the dependencies.
Gradle file
buildscript {
ext {
springBootVersion = '1.5.9.RELEASE'
}
repositories {
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
}
}
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'org.springframework.boot'
group = 'com.domain'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = 1.8
compileJava.options.encoding = "UTF-8"
compileTestJava.options.encoding = "UTF-8"
repositories {
mavenCentral()
}
dependencies {
compile('org.springframework.boot:spring-boot-starter-actuator')
compile('org.springframework.boot:spring-boot-actuator-docs')
compile('org.springframework.boot:spring-boot-starter-data-jpa')
compile('org.springframework.boot:spring-boot-starter-security')
compile('org.springframework.boot:spring-boot-starter-validation')
compile('org.springframework.boot:spring-boot-starter-web')
runtime('org.springframework.boot:spring-boot-devtools')
runtime('org.postgresql:postgresql')
testCompile('org.springframework.boot:spring-boot-starter-test')
testCompile('org.springframework.security:spring-security-test')
}
UPDATE of Gradle file
...
compile('org.springframework.boot:spring-boot-starter-validation'){
exclude group: 'org.hibernate', module: 'hibernate-validator:5.3.6.Final'
}
compile 'org.hibernate:hibernate-validator:6.0.7.Final'
...
| \--- org.hibernate:hibernate-validator:5.3.6.Final -> 6.0.7.Final
| \--- org.hibernate.validator:hibernate-validator:6.0.7.Final
| +--- javax.validation:validation-api:2.0.1.Final -> 1.1.0.Final
| +--- org.jboss.logging:jboss-logging:3.3.0.Final -> 3.3.1.Final
| \--- com.fasterxml:classmate:1.3.1 -> 1.3.4
have i some thing else to do ? while inside the entity i still have the same error. with new one : The type NotEmpty is deprecated (as shows the doc here)
The problem is that #PastOrPresent constraint is a part of Bean Validation 2.0 (see here), while the Spring Boot is still using Hibernate Validator 5.3 by default (see the dependencies here), which is BeanValidation 1.1. If you'd like to use this new constraint you would need to have an explicit dependency for Hibernate Validator 6.0 and exclude 5.4 version from your current dependencies.