Excluded dependence comes back when spring-boot plugin is applied

My project structure has 2 levels in intellij using gradle wrapper.
My lower level project has dependence
org.springframework.data:spring-data-elasticsearch:1.3.4.RELEASE
which comes with elasticsearch 1.5.2
I exclude elasticsearch 1.5.2 and manually include 2.0.0
all is working fine.

build.gradle

group 'com.ohmyapp'
version '1.0-SNAPSHOT'

apply plugin: 'java'

repositories {
    mavenCentral()
}

dependencies {
    compile ("org.springframework.data:spring-data-jpa:1.9.2.RELEASE")
    compile ("org.springframework.data:spring-data-elasticsearch:1.3.4.RELEASE") {
        exclude   module: 'elasticsearch'
        }
    compile 'org.elasticsearch:elasticsearch:2.0.0'
}

When I include this project as a compile dependence

dependencies {
    compile project(':module1')
    compile 'org.springframework.boot:spring-boot-starter:1.3.1.RELEASE'
    testCompile group: 'junit', name: 'junit', version: '4.11'
}

elasticsearch 2.0.0 is correctly pulled in.

When I apply spring-boot plugin, elasticsearch 1.5.2 comes back. What is the problem here?

build.gradle

group 'com.ohmyapp'
version '1.0-SNAPSHOT'

apply plugin: 'java'
apply plugin: 'spring-boot'

buildscript {
    repositories {
        mavenCentral()
        jcenter()
        maven {url 'https://plugins.gradle.org/m2'}
    }

    dependencies {
        classpath 'org.springframework.boot:spring-boot-gradle-plugin:1.3.1.RELEASE'
    }
}

repositories {
    mavenCentral()
}

dependencies {
    compile project(':module1')
    compile 'org.springframework.boot:spring-boot-starter:1.3.1.RELEASE'
    testCompile group: 'junit', name: 'junit', version: '4.11'
}

This is something the spring-boot plugin is doing through the Spring dependency-management-plugin: https://github.com/spring-gradle-plugins/dependency-management-plugin

The Spring dependency-management-plugin adds its own rules to force particular versions to be used, which ignores the exclusion you’ve added.

You can tell this by running gradle dependencyInsight --configuration compile --dependency elasticsearch

You should see something like:

org.elasticsearch:elasticsearch:1.5.2 (selected by rule)

org.elasticsearch:elasticsearch:2.0.0 -> 1.5.2
\--- project :module1
     \--- compile

org.springframework.data:spring-data-elasticsearch:1.3.2.RELEASE (selected by rule)

org.springframework.data:spring-data-elasticsearch:1.3.4.RELEASE -> 1.3.2.RELEASE
\--- project :module1
     \--- compile

The “selected by rule” part is the clue that there’s something programmatically selecting that version. If you run with --info, you’ll see output from the plugin describing all the versions it’s pinning.

You can get around this by adding your own rule. Instead of excluding and adding the correct version of elasticsearch, you can just configure Gradle to always replace the elasticsearch dependency with the correct one:

in the root project build.gradle:

allprojects {
    configurations.all {
        resolutionStrategy {
            dependencySubstitution {
                substitute module('org.elasticsearch:elasticsearch') with module('org.elasticsearch:elasticsearch:2.0.0')
            }
        }
    }
}

That tells Gradle to always substitute a dependency with group org.elasticsearch and name elasticsearch with the elasticsearch GAV for 2.0.0. Running dependencyInsight again should give you something like:

org.elasticsearch:elasticsearch:2.0.0 (selected by rule)

org.elasticsearch:elasticsearch:1.5.2 -> 2.0.0
\--- org.springframework.data:spring-data-elasticsearch:1.3.2.RELEASE
     \--- project :module1
          \--- compile

org.springframework.data:spring-data-elasticsearch:1.3.2.RELEASE (selected by rule)

org.springframework.data:spring-data-elasticsearch:1.3.4.RELEASE -> 1.3.2.RELEASE
\--- project :module1
     \--- compile

There may be other ways of configuring the Spring dependency-management-plugin, but I’m not familiar enough with it to suggest what that may be.

thanks for your reply
I got an exception. may be there is a typo.
FAILURE: Build failed with an exception.

  • Where:
    Build file ‘C:\mystuff\projects\ohmyplugin\build.gradle’ line: 26

  • What went wrong:
    A problem occurred evaluating root project ‘ohmyplugin’.

No such property: substitute for class: org.gradle.api.internal.artifacts.ivyservice.dependencysubstitution.DefaultDependencySubstitutions

  • Try:
    Run with --info or --debug option to get more log output.

  • Exception is:
    org.gradle.api.GradleScriptException: A problem occurred evaluating root project ‘ohmyplugin’.
    at org.gradle.groovy.scripts.internal.DefaultScriptRunnerFactory$ScriptRunnerImpl.run(DefaultScriptRunnerFactory.java:93)
    at org.gradle.configuration.DefaultScriptPluginFactory$ScriptPluginImpl$2.run(DefaultScriptPluginFactory.java:177)
    at org.gradle.configuration.ProjectScriptTarget.addConfiguration(ProjectScriptTarget.java:77)
    at org.gradle.configuration.DefaultScriptPluginFactory$ScriptPluginImpl.apply(DefaultScriptPluginFactory.java:182)
    at org.gradle.configuration.project.BuildScriptProcessor.execute(BuildScriptProcessor.java:38)
    at org.gradle.configuration.project.BuildScriptProcessor.execute(BuildScriptProcessor.java:25)
    at org.gradle.configuration.project.ConfigureActionsProjectEvaluator.evaluate(ConfigureActionsProjectEvaluator.java:34)
    at org.gradle.configuration.project.LifecycleProjectEvaluator.evaluate(LifecycleProjectEvaluator.java:55)
    at org.gradle.api.internal.project.AbstractProject.evaluate(AbstractProject.java:540)
    at org.gradle.api.internal.project.AbstractProject.evaluate(AbstractProject.java:93)
    at org.gradle.execution.TaskPathProjectEvaluator.configureHierarchy(TaskPathProjectEvaluator.java:42)
    at org.gradle.configuration.DefaultBuildConfigurer.configure(DefaultBuildConfigurer.java:35)
    at org.gradle.initialization.DefaultGradleLauncher$2.run(DefaultGradleLauncher.java:124)
    at org.gradle.internal.Factories$1.create(Factories.java:22)
    at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:91)
    at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:53)
    at org.gradle.initialization.DefaultGradleLauncher.doBuildStages(DefaultGradleLauncher.java:121)
    at org.gradle.initialization.DefaultGradleLauncher.access$200(DefaultGradleLauncher.java:32)
    at org.gradle.initialization.DefaultGradleLauncher$1.create(DefaultGradleLauncher.java:98)
    at org.gradle.initialization.DefaultGradleLauncher$1.create(DefaultGradleLauncher.java:92)
    at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:91)
    at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:63)
    at org.gradle.initialization.DefaultGradleLauncher.doBuild(DefaultGradleLauncher.java:92)
    at org.gradle.initialization.DefaultGradleLauncher.run(DefaultGradleLauncher.java:83)
    at org.gradle.launcher.exec.InProcessBuildActionExecuter$DefaultBuildController.run(InProcessBuildActionExecuter.java:99)
    at org.gradle.tooling.internal.provider.ExecuteBuildActionRunner.run(ExecuteBuildActionRunner.java:28)
    at org.gradle.launcher.exec.ChainingBuildActionRunner.run(ChainingBuildActionRunner.java:35)
    at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:48)
    at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:30)
    at org.gradle.launcher.exec.ContinuousBuildActionExecuter.execute(ContinuousBuildActionExecuter.java:81)
    at org.gradle.launcher.exec.ContinuousBuildActionExecuter.execute(ContinuousBuildActionExecuter.java:46)
    at org.gradle.launcher.exec.DaemonUsageSuggestingBuildActionExecuter.execute(DaemonUsageSuggestingBuildActionExecuter.java:51)
    at org.gradle.launcher.exec.DaemonUsageSuggestingBuildActionExecuter.execute(DaemonUsageSuggestingBuildActionExecuter.java:28)
    at org.gradle.launcher.cli.RunBuildAction.run(RunBuildAction.java:43)
    at org.gradle.internal.Actions$RunnableActionAdapter.execute(Actions.java:173)
    at org.gradle.launcher.cli.CommandLineActionFactory$ParseAndBuildAction.execute(CommandLineActionFactory.java:239)
    at org.gradle.launcher.cli.CommandLineActionFactory$ParseAndBuildAction.execute(CommandLineActionFactory.java:212)
    at org.gradle.launcher.cli.JavaRuntimeValidationAction.execute(JavaRuntimeValidationAction.java:35)
    at org.gradle.launcher.cli.JavaRuntimeValidationAction.execute(JavaRuntimeValidationAction.java:24)
    at org.gradle.launcher.cli.ExceptionReportingAction.execute(ExceptionReportingAction.java:33)
    at org.gradle.launcher.cli.ExceptionReportingAction.execute(ExceptionReportingAction.java:22)
    at org.gradle.launcher.cli.CommandLineActionFactory$WithLogging.execute(CommandLineActionFactory.java:205)
    at org.gradle.launcher.cli.CommandLineActionFactory$WithLogging.execute(CommandLineActionFactory.java:169)
    at org.gradle.launcher.Main.doAction(Main.java:33)
    at org.gradle.launcher.bootstrap.EntryPoint.run(EntryPoint.java:45)
    at org.gradle.launcher.bootstrap.ProcessBootstrap.runNoExit(ProcessBootstrap.java:55)
    at org.gradle.launcher.bootstrap.ProcessBootstrap.run(ProcessBootstrap.java:36)
    at org.gradle.launcher.GradleMain.main(GradleMain.java:23)
    Caused by: groovy.lang.MissingPropertyException: No such property: substitute for class: org.gradle.api.internal.artifacts.ivyservice.dependencysubstitution.DefaultDependencySubstitutions
    at build_3fbwyyza81aa2d6traca54xlq$_run_closure2$_closure4$_closure5$_closure6.doCall(C:\mystuff\projects\ohmyplugin\build.gradle:26)
    at org.gradle.api.internal.ClosureBackedAction.execute(ClosureBackedAction.java:67)
    at org.gradle.api.internal.artifacts.ivyservice.resolutionstrategy.DefaultResolutionStrategy.dependencySubstitution(DefaultResolutionStrategy.java:162)
    at org.gradle.api.internal.artifacts.ivyservice.resolutionstrategy.DefaultResolutionStrategy_Decorated.dependencySubstitution(Unknown Source)
    at org.gradle.internal.metaobject.BeanDynamicObject$MetaClassAdapter.invokeMethod(BeanDynamicObject.java:374)
    at org.gradle.internal.metaobject.BeanDynamicObject.invokeMethod(BeanDynamicObject.java:169)
    at org.gradle.internal.metaobject.CompositeDynamicObject.invokeMethod(CompositeDynamicObject.java:96)
    at org.gradle.internal.metaobject.MixInClosurePropertiesAsMethodsDynamicObject.invokeMethod(MixInClosurePropertiesAsMethodsDynamicObject.java:30)
    at org.gradle.internal.metaobject.ConfigureDelegate.invokeMethod(ConfigureDelegate.java:59)
    at build_3fbwyyza81aa2d6traca54xlq$_run_closure2$_closure4$_closure5.doCall(C:\mystuff\projects\ohmyplugin\build.gradle:25)
    at org.gradle.api.internal.ClosureBackedAction.execute(ClosureBackedAction.java:67)
    at org.gradle.util.ConfigureUtil.configure(ConfigureUtil.java:107)
    at org.gradle.api.internal.artifacts.configurations.DefaultConfiguration.resolutionStrategy(DefaultConfiguration.java:566)
    at build_3fbwyyza81aa2d6traca54xlq$_run_closure2$_closure4.doCall(C:\mystuff\projects\ohmyplugin\build.gradle:24)
    at org.gradle.api.internal.ClosureBackedAction.execute(ClosureBackedAction.java:67)
    at org.gradle.api.internal.DefaultDomainObjectCollection.all(DefaultDomainObjectCollection.java:110)
    at org.gradle.api.internal.DefaultDomainObjectCollection.all(DefaultDomainObjectCollection.java:115)
    at org.gradle.api.DomainObjectCollection$all.call(Unknown Source)
    at build_3fbwyyza81aa2d6traca54xlq$_run_closure2.doCall(C:\mystuff\projects\ohmyplugin\build.gradle:23)
    at org.gradle.api.internal.ClosureBackedAction.execute(ClosureBackedAction.java:67)
    at org.gradle.util.ConfigureUtil.configure(ConfigureUtil.java:107)
    at org.gradle.api.internal.project.AbstractProject.configure(AbstractProject.java:888)
    at org.gradle.api.internal.project.AbstractProject.configure(AbstractProject.java:893)
    at org.gradle.api.internal.project.AbstractProject.allprojects(AbstractProject.java:880)
    at org.gradle.internal.metaobject.BeanDynamicObject$MetaClassAdapter.invokeMethod(BeanDynamicObject.java:374)
    at org.gradle.internal.metaobject.BeanDynamicObject.invokeMethod(BeanDynamicObject.java:169)
    at org.gradle.internal.metaobject.CompositeDynamicObject.invokeMethod(CompositeDynamicObject.java:96)
    at org.gradle.internal.metaobject.MixInClosurePropertiesAsMethodsDynamicObject.invokeMethod(MixInClosurePropertiesAsMethodsDynamicObject.java:30)
    at org.gradle.internal.metaobject.AbstractDynamicObject.invokeMethod(AbstractDynamicObject.java:163)
    at org.gradle.groovy.scripts.BasicScript.methodMissing(BasicScript.java:79)
    at build_3fbwyyza81aa2d6traca54xlq.run(C:\mystuff\projects\ohmyplugin\build.gradle:22)
    at org.gradle.groovy.scripts.internal.DefaultScriptRunnerFactory$ScriptRunnerImpl.run(DefaultScriptRunnerFactory.java:91)
    … 47 more

BUILD FAILED

Total time: 6.752 secs

The above code works in linux OS but not windows.
both machine running jdk8, intellij 2016.1.3.