Search code examples
springgradlespring-bootgradle-pluginspring-boot-gradle-plugin

Spring boot multiple gradle projects dependcy mangament -> Cannot change dependencies of configuration


I have few projects each with structure something like that

projectA
| - projectA-module1
| - projectA-module2
| - projectA-service

project-service -> this module has applied spring boot plugin, it is deployable all other modules are dependencies for this module. Each module needs only specific spring dependencies for ex. module1 need mail api, module2 need only rabbitmq api etc. I wanted to void adding spring boot plugin with all of it dependencies to each of the modules. So I thought that I can use dependency-management-plugin and add to each moduleX and configure it and for module service just configure it because it will be already added by plugin spring boot. In my custom plugin I have this function to do this:

protected def addAndConfigureDependencyManagementExtension(){
    if(project.name.matches("[a-z]*-service")){
        LOGGER.info("Project ${project.name} have allready applied plugin ${SPRING_DEPENDENCY_PLUGIN_ID}. Just configure it")
        validateSpringBootVersions()
    }else {
        DependencyManagementPlugin dependencyManagementPlugin = new DependencyManagementPlugin()
        dependencyManagementPlugin.apply(project)
    }
    project.extensions.configure(DependencyManagementExtension, new ClosureBackedAction<DependencyManagementExtension>({
        imports {
            mavenBom("org.springframework.cloud:spring-cloud-dependencies:Brixton.BUILD-SNAPSHOT")
        }
    }))
}

Here is my moduleX build.

apply plugin: 'myplugin'

dependencies {
    compile 'org.springframework:spring-context'
    compile 'org.springframework:spring-web'
}

Here is build.gradle for my service module:

buildscript {
    ext {
        springBootVersion = '1.3.2.RELEASE'
    }

    repositories {
        mavenLocal()
        mavenCentral()
    }

    dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
    }
}

apply plugin: 'spring-boot'
apply plugin: 'my-plugin'

dependencies {
    compile('org.springframework.boot:spring-boot-starter-actuator')
    compile('org.springframework.boot:spring-boot-starter-remote-shell')
    compile('org.springframework.boot:spring-boot-starter-web')
    testCompile('org.springframework.boot:spring-boot-starter-test')
    compile project(':my-project')
}

And the issue is that when I am trying to run ./gradlew build I am getting:

Cannot change dependencies of configuration 'detachedConfiguration1' after it has been resolved.

I don't know exactly why it is occurring and how to solve this. Thanks in advance for any suggestion, tips. Perhaps that are easier way | or already available solutions to achieve dependency consistency?

EDIT: Here is stacktrace:

* Exception is:
org.gradle.api.InvalidUserDataException: Cannot change dependencies of configuration 'detachedConfiguration1' after it has been resolved.
    at org.gradle.api.internal.artifacts.configurations.DefaultConfiguration.validateMutation(DefaultConfiguration.java:597)
    at org.gradle.api.internal.artifacts.configurations.DefaultConfiguration$2.run(DefaultConfiguration.java:145)
    at org.gradle.api.internal.DefaultDomainObjectCollection.assertMutable(DefaultDomainObjectCollection.java:267)
    at org.gradle.api.internal.DefaultDomainObjectCollection.add(DefaultDomainObjectCollection.java:158)
    at org.gradle.api.internal.DelegatingDomainObjectSet.add(DelegatingDomainObjectSet.java:81)
    at java_util_Set$add$0.call(Unknown Source)
    at io.spring.gradle.dependencymanagement.DependencyManagement$_resolve_closure2.doCall(DependencyManagement.groovy:150)
    at io.spring.gradle.dependencymanagement.DependencyManagement.resolve(DependencyManagement.groovy:150)
    at io.spring.gradle.dependencymanagement.DependencyManagement.resolveIfNecessary(DependencyManagement.groovy:130)
    at io.spring.gradle.dependencymanagement.DependencyManagement.getExclusions(DependencyManagement.groovy:124)
    at io.spring.gradle.dependencymanagement.DependencyManagement$getExclusions$2.call(Unknown Source)
    at io.spring.gradle.dependencymanagement.DependencyManagementContainer.getExclusions(DependencyManagementContainer.groovy:104)
    at io.spring.gradle.dependencymanagement.DependencyManagementContainer$getExclusions$2.call(Unknown Source)
    at io.spring.gradle.dependencymanagement.exclusions.ExclusionConfiguringAction.findExcludedDependencies(ExclusionConfiguringAction.groovy:99)
    at io.spring.gradle.dependencymanagement.exclusions.ExclusionConfiguringAction.applyMavenExclusions(ExclusionConfiguringAction.groovy:76)
    at io.spring.gradle.dependencymanagement.exclusions.ExclusionConfiguringAction.this$2$applyMavenExclusions(ExclusionConfiguringAction.groovy)
    at io.spring.gradle.dependencymanagement.exclusions.ExclusionConfiguringAction.execute(ExclusionConfiguringAction.groovy:71)
    at io.spring.gradle.dependencymanagement.exclusions.ExclusionConfiguringAction.execute(ExclusionConfiguringAction.groovy)
    at org.gradle.internal.event.BroadcastDispatch$ActionInvocationHandler.dispatch(BroadcastDispatch.java:93)
    at org.gradle.internal.event.BroadcastDispatch$ActionInvocationHandler.dispatch(BroadcastDispatch.java:82)
    at org.gradle.internal.event.AbstractBroadcastDispatch.dispatch(AbstractBroadcastDispatch.java:44)
    at org.gradle.internal.event.BroadcastDispatch.dispatch(BroadcastDispatch.java:79)
    at org.gradle.internal.event.BroadcastDispatch.dispatch(BroadcastDispatch.java:30)
    at org.gradle.messaging.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:93)
    at com.sun.proxy.$Proxy21.beforeResolve(Unknown Source)
    at org.gradle.api.internal.artifacts.configurations.DefaultConfiguration.performPreResolveActions(DefaultConfiguration.java:384)
    at org.gradle.api.internal.artifacts.configurations.DefaultConfiguration.resolveGraphIfRequired(DefaultConfiguration.java:365)
    at org.gradle.api.internal.artifacts.configurations.DefaultConfiguration.resolveNow(DefaultConfiguration.java:342)
    at org.gradle.api.internal.artifacts.configurations.DefaultConfiguration.getResolvedConfiguration(DefaultConfiguration.java:335)
    at org.gradle.api.internal.artifacts.configurations.DefaultConfiguration_Decorated.getResolvedConfiguration(Unknown Source)
    at org.gradle.api.internal.artifacts.configurations.DefaultConfiguration$ConfigurationFileCollection.getFiles(DefaultConfiguration.java:661)
    at org.gradle.api.internal.artifacts.configurations.DefaultConfiguration.getFiles(DefaultConfiguration.java:288)
    at org.gradle.api.internal.artifacts.configurations.DefaultConfiguration_Decorated.getFiles(Unknown Source)
    at org.gradle.api.internal.file.collections.DefaultFileCollectionResolveContext$FileTreeConverter.convertInto(DefaultFileCollectionResolveContext.java:200)
    at org.gradle.api.internal.file.collections.DefaultFileCollectionResolveContext.doResolve(DefaultFileCollectionResolveContext.java:107)
    at org.gradle.api.internal.file.collections.DefaultFileCollectionResolveContext.resolveAsFileTrees(DefaultFileCollectionResolveContext.java:78)
    at org.gradle.api.internal.file.collections.DefaultFileCollectionResolveContext$FileTreeConverter.convertInto(DefaultFileCollectionResolveContext.java:186)
    at org.gradle.api.internal.file.collections.DefaultFileCollectionResolveContext.doResolve(DefaultFileCollectionResolveContext.java:102)
    at org.gradle.api.internal.file.collections.DefaultFileCollectionResolveContext.resolveAsFileTrees(DefaultFileCollectionResolveContext.java:78)
    at org.gradle.api.internal.changedetection.state.DefaultFileCollectionSnapshotter.visitFiles(DefaultFileCollectionSnapshotter.java:85)
    at org.gradle.api.internal.changedetection.state.DefaultFileCollectionSnapshotter.snapshot(DefaultFileCollectionSnapshotter.java:54)
    at org.gradle.api.internal.changedetection.rules.TaskUpToDateState.<init>(TaskUpToDateState.java:56)
    at org.gradle.api.internal.changedetection.changes.DefaultTaskArtifactStateRepository$TaskArtifactStateImpl.getStates(DefaultTaskArtifactStateRepository.java:132)
    at org.gradle.api.internal.changedetection.changes.DefaultTaskArtifactStateRepository$TaskArtifactStateImpl.isUpToDate(DefaultTaskArtifactStateRepository.java:70)
    at org.gradle.api.internal.tasks.execution.SkipUpToDateTaskExecuter.execute(SkipUpToDateTaskExecuter.java:52)
    at org.gradle.api.internal.tasks.execution.ValidatingTaskExecuter.execute(ValidatingTaskExecuter.java:58)
    at org.gradle.api.internal.tasks.execution.SkipEmptySourceFilesTaskExecuter.execute(SkipEmptySourceFilesTaskExecuter.java:52)
    at org.gradle.api.internal.tasks.execution.SkipTaskWithNoActionsExecuter.execute(SkipTaskWithNoActionsExecuter.java:52)
    at org.gradle.api.internal.tasks.execution.SkipOnlyIfTaskExecuter.execute(SkipOnlyIfTaskExecuter.java:53)
    at org.gradle.api.internal.tasks.execution.ExecuteAtMostOnceTaskExecuter.execute(ExecuteAtMostOnceTaskExecuter.java:43)
    at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter$EventFiringTaskWorker.execute(DefaultTaskGraphExecuter.java:203)
    at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter$EventFiringTaskWorker.execute(DefaultTaskGraphExecuter.java:185)
    at org.gradle.execution.taskgraph.AbstractTaskPlanExecutor$TaskExecutorWorker.processTask(AbstractTaskPlanExecutor.java:66)
    at org.gradle.execution.taskgraph.AbstractTaskPlanExecutor$TaskExecutorWorker.run(AbstractTaskPlanExecutor.java:50)
    at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor.process(DefaultTaskPlanExecutor.java:25)
    at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter.execute(DefaultTaskGraphExecuter.java:110)
    at org.gradle.execution.SelectedTaskExecutionAction.execute(SelectedTaskExecutionAction.java:37)
    at org.gradle.execution.DefaultBuildExecuter.execute(DefaultBuildExecuter.java:37)
    at org.gradle.execution.DefaultBuildExecuter.access$000(DefaultBuildExecuter.java:23)
    at org.gradle.execution.DefaultBuildExecuter$1.proceed(DefaultBuildExecuter.java:43)
    at org.gradle.execution.DryRunBuildExecutionAction.execute(DryRunBuildExecutionAction.java:32)
    at org.gradle.execution.DefaultBuildExecuter.execute(DefaultBuildExecuter.java:37)
    at org.gradle.execution.DefaultBuildExecuter.execute(DefaultBuildExecuter.java:30)
    at org.gradle.initialization.DefaultGradleLauncher$4.run(DefaultGradleLauncher.java:154)
    at org.gradle.internal.Factories$1.create(Factories.java:22)
    at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:90)
    at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:52)
    at org.gradle.initialization.DefaultGradleLauncher.doBuildStages(DefaultGradleLauncher.java:151)
    at org.gradle.initialization.DefaultGradleLauncher.access$200(DefaultGradleLauncher.java:32)
    at org.gradle.initialization.DefaultGradleLauncher$1.create(DefaultGradleLauncher.java:99)
    at org.gradle.initialization.DefaultGradleLauncher$1.create(DefaultGradleLauncher.java:93)
    at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:90)
    at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:62)
    at org.gradle.initialization.DefaultGradleLauncher.doBuild(DefaultGradleLauncher.java:93)
    at org.gradle.initialization.DefaultGradleLauncher.run(DefaultGradleLauncher.java:82)
    at org.gradle.launcher.exec.InProcessBuildActionExecuter$DefaultBuildController.run(InProcessBuildActionExecuter.java:94)
    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:43)
    at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:28)
    at org.gradle.launcher.exec.ContinuousBuildActionExecuter.execute(ContinuousBuildActionExecuter.java:77)
    at org.gradle.launcher.exec.ContinuousBuildActionExecuter.execute(ContinuousBuildActionExecuter.java:47)
    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:170)
    at org.gradle.launcher.cli.CommandLineActionFactory$ParseAndBuildAction.execute(CommandLineActionFactory.java:237)
    at org.gradle.launcher.cli.CommandLineActionFactory$ParseAndBuildAction.execute(CommandLineActionFactory.java:210)
    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.CommandLineActionFactory$WithLogging.execute(CommandLineActionFactory.java:206)
    at org.gradle.launcher.cli.CommandLineActionFactory$WithLogging.execute(CommandLineActionFactory.java:169)
    at org.gradle.launcher.cli.ExceptionReportingAction.execute(ExceptionReportingAction.java:33)
    at org.gradle.launcher.cli.ExceptionReportingAction.execute(ExceptionReportingAction.java:22)
    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:54)
    at org.gradle.launcher.bootstrap.ProcessBootstrap.run(ProcessBootstrap.java:35)
    at org.gradle.launcher.GradleMain.main(GradleMain.java:23)
    at org.gradle.wrapper.BootstrapMainStarter.start(BootstrapMainStarter.java:30)
    at org.gradle.wrapper.WrapperExecutor.execute(WrapperExecutor.java:129)
    at org.gradle.wrapper.GradleWrapperMain.main(GradleWrapperMain.java:61)

EDIT 2

I have created two github projects to reproduce issue. Here are links project and plugin. What I noticed that on Intellij 15 refresh gradle project does not work because of "Error:Cannot change dependencies of configuration 'detachedConfiguration1' after it has been resolved." However gradle build from command line almost works. Only problem that exists in new setup is that configuring dependency management plugin from my plugin seems not to working. I need to repeat dependencyManagement in test-service/build.gradle. There is something wrong with the code?


Solution

  • In your reproduction your plugin contains this logic:

    @Override
    void apply(Project project) {
        if(project.name.matches("[a-z]*-service")){
            println("Skipping dependency managament plugin for ${project.name}")
            return
        }else {
            println("Added dependency managament plugin for ${project.name}")
            DependencyManagementPlugin dependencyManagementPlugin = new DependencyManagementPlugin()
            dependencyManagementPlugin.apply(project)
        }
        project.extensions.configure(DependencyManagementExtension, new ClosureBackedAction<DependencyManagementExtension>({
            imports {
                mavenBom("org.springframework.cloud:spring-cloud-dependencies:Brixton.BUILD-SNAPSHOT")
            }
        }))
    }
    

    And you said:

    Only problem that exists in new setup is that configuring dependency management plugin from my plugin seems not to working. I need to repeat dependencyManagement in test-service/build.gradle

    This is due to the return statement in the first if block. Rather than just skipping the logic the applies the dependency management plugin, you're also skipping the logic that imports the Spring Cloud bom.

    Without that return statement, your sample project builds successfully for me with ./gradlew clean build.