I am having a problem with a transitive dependency of my grails-flyway
plugin. org.grails.plugins:grails-flyway:0.2.1
declares a dependency to org.flywaydb:flyway-core:4.0.1
. When I include the plugin into my Grails 3.1.6 project Gradle downgrades Flyway to version 3.2.1.
+--- org.grails.plugins:grails-flyway:0.2.1 | \--- org.flywaydb:flyway-core:4.0.1 -> 3.2.1
My Gradle build file looks like this
buildscript { ext { grailsVersion = project.grailsVersion } repositories { maven { url "https://repo.grails.org/grails/core" } } dependencies { classpath "org.grails:grails-gradle-plugin:$grailsVersion" classpath "com.bertramlabs.plugins:asset-pipeline-gradle:${assetPipelinePluginVersion}" classpath "org.grails.plugins:hibernate5:5.0.5" classpath 'com.github.ben-manes:gradle-versions-plugin:0.12.0' } } version "0.40.15" group "zsc.supporter" apply plugin: "war" apply plugin: "org.grails.grails-web" apply plugin: "org.grails.grails-gsp" apply plugin: "org.grails.grails-doc" apply plugin: "asset-pipeline" apply plugin: 'com.github.ben-manes.versions' ext { grailsVersion = project.grailsVersion gradleWrapperVersion = project.gradleWrapperVersion } repositories { maven { url "https://repo.grails.org/grails/core" } maven { url "https://dl.bintray.com/saw303/plugins" } } dependencyManagement { imports { mavenBom "org.grails:grails-bom:$grailsVersion" } applyMavenExclusions false } dependencies { compile "org.springframework.boot:spring-boot-starter-logging" compile "org.springframework.boot:spring-boot-autoconfigure" compile "org.grails:grails-core" compile "org.springframework.boot:spring-boot-starter-actuator" compile "org.springframework.boot:spring-boot-starter-tomcat" compile "org.grails:grails-dependencies" compile "org.grails:grails-web-boot" compile "org.grails.plugins:cache" compile "org.grails.plugins:scaffolding" compile "org.grails.plugins:hibernate4" compile "org.hibernate:hibernate-ehcache" console "org.grails:grails-console" profile "org.grails.profiles:web:3.1.6" runtime "com.bertramlabs.plugins:asset-pipeline-grails:${assetPipelinePluginVersion}" runtime "com.h2database:h2" testCompile "org.grails:grails-plugin-testing" testCompile "org.grails.plugins:geb" testRuntime "org.seleniumhq.selenium:selenium-htmlunit-driver:2.52.0" testRuntime "net.sourceforge.htmlunit:htmlunit:2.21" compile "org.grails.plugins:spring-security-core:3.0.4" compile "org.grails.plugins:quartz:2.0.8" compile "org.grails.plugins:mail:2.0.0.RC4" compile "eu.bitwalker:UserAgentUtils:1.18" compile 'org.mnode.ical4j:ical4j:1.0.7' compile 'org.grails.plugins:browser-detection:3.1.0' compile "com.googlecode.libphonenumber:libphonenumber:7.3.1" runtime 'org.grails.plugins:grails-flyway:0.2.1' testCompile "org.grails.plugins:grails-wizer:0.3" testCompile 'org.grails:grails-datastore-test-support:5.0.5.RELEASE' runtime 'mysql:mysql-connector-java:5.1.29' } task wrapper(type: Wrapper) { gradleVersion = gradleWrapperVersion } assets { minifyJs = true minifyCss = true }
Currently I do not understand why Gradle downgrades my transitive dependency. Can someone provide on this?
I am aware that I can force the flyway-core:4.0.1
dependency in my build.gradle
but I would like to understand what the downgrade causes.
UPDATE-1
When I run gradle dependencies | grep flyway
I get the following output.
+--- org.grails.plugins:grails-flyway:0.2.1 | \--- org.flywaydb:flyway-core:4.0.1 -> 3.2.1 +--- org.grails.plugins:grails-flyway:0.2.1 | \--- org.flywaydb:flyway-core:4.0.1 -> 3.2.1 +--- org.grails.plugins:grails-flyway:0.2.1 | \--- org.flywaydb:flyway-core:4.0.1 -> 3.2.1 +--- org.grails.plugins:grails-flyway:0.2.1 | \--- org.flywaydb:flyway-core:4.0.1 -> 3.2.1
Please find the complete output at pastebin. The grails-flyway
plugin and its pom.xml can be found at Bintray.
UPDATE-2
I tried to force Gradle to use org.flywaydb:flyway-core:4.0.1
according to Gradles Reference.
configurations.all { resolutionStrategy.force 'org.flywaydb:flyway-core:4.0.1' }
That does not affect the problem. The dependency tree still uses version 3.2.1 of flyway-core
.
+--- org.grails.plugins:grails-flyway:0.2.1 | \--- org.flywaydb:flyway-core:4.0.1 -> 3.2.1
UPDATE-3
Gradles dependencyInsight
command
gradle dependencyInsight --dependency flyway-core --configuration runtime
results in
:dependencyInsight org.flywaydb:flyway-core:3.2.1 (selected by rule) org.flywaydb:flyway-core:4.0.1 -> 3.2.1 \--- org.grails.plugins:grails-flyway:0.2.1 \--- runtime
What means (selected by rule)
?
"Solution" - or how to work it around
I was not able to find the rule that causes Gradle to use flyway-core:3.2.1
instead of flyway-core:4.0.1
. But I found a way to work around the problem.
I added the following to my build.gradle
to modify my Gradle runtime
resolution strategy.
configurations.runtime.resolutionStrategy { eachDependency { DependencyResolveDetails det -> if (det.requested.name == 'flyway-core' && det.requested.group == 'org.flywaydb') { det.useVersion(det.requested.version) } } }
Transitive dependency Releases of a module hosted on a repository can provide metadata to declare those transitive dependencies. By default, Gradle resolves transitive dependencies automatically. The version selection for transitive dependencies can be influenced by declaring dependency constraints.
When you specify a dependency in your build script, you can provide an exclude rule at the same time telling Gradle not to pull in the specified transitive dependency. For example, say we have a Gradle project that depends on Google's Guava library, or more specifically com.
Gradle. To override the version of a transitive dependency in Gradle, exclude it from the declared dependency that pulls it in, and then explicitly declare the version that you prefer to use in your build.
The thing causing it is the spring-boot-dependencies-1.3.3.RELEASE.pom
This forcing the flyway version to 3.2.1
According to the Spring Boot docs you should be able to add a line like this to your build.gradle
: ext['flyway.version'] = '4.0.1'
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With