Spring引导多个gradle项目依赖管理->无法更改配置的依赖关系

Posted

技术标签:

【中文标题】Spring引导多个gradle项目依赖管理->无法更改配置的依赖关系【英文标题】:Spring boot multiple gradle projects dependcy mangament -> Cannot change dependencies of configuration 【发布时间】:2016-05-25 11:09:53 【问题描述】:

我有几个项目都有类似的结构

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

project-service -> 这个模块已经应用了spring boot插件,它是可部署的,所有其他模块都是这个模块的依赖项。每个模块只需要特定的弹簧依赖关系。 module1 需要 mail api,module2 只需要 rabbitmq api 等。我想避免将 spring boot 插件及其所有依赖项添加到每个模块。所以我认为我可以使用依赖管理插件并添加到每个moduleX并对其进行配置,对于模块服务只需配置它,因为它已经被插件spring boot添加了。在我的自定义插件中,我有这个功能:

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")
        
    ))

这是我的 moduleX 构建。

apply plugin: 'myplugin'

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

这是我的服务模块的 build.gradle:

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')

问题是,当我尝试运行 ./gradlew build 时,我得到:

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

我不知道它发生的确切原因以及如何解决这个问题。提前感谢您的任何建议,提示。也许这是更简单的方法|还是已经可用的解决方案来实现依赖一致性?

编辑: 这是堆栈跟踪:

* 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)

编辑 2

我创建了两个 github 项目来重现问题。这里是链接 project 和 plugin。我注意到在 Intellij 15 上刷新 gradle 项目不起作用,因为“错误:解决后无法更改配置 'detachedConfiguration1' 的依赖关系。”然而,从命令行构建的 gradle 几乎可以工作。新设置中唯一存在的问题是从我的插件配置依赖管理插件似乎不起作用。我需要在 test-service/build.gradle 中重复依赖管理。代码有问题吗?

【问题讨论】:

失败的堆栈跟踪是什么?您可以使用 --stacktrace 运行以让 Gradle 向您展示它。 依赖管理插件使用分离的配置来解析任何已导入的 bom。当它尝试解决该配置但它已经解决时,就会发生您看到的失败。这不应该发生(插件会跟踪配置是否已经解决)。我无法从您的描述中拼凑出为什么会发生这种情况。您能否分享重现问题所需的所有代码和build.grade 脚本? 添加到 github 的链接 【参考方案1】:

在您的复制中,您的插件包含以下逻辑:

@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")
        
    ))

你说:

新设置中唯一存在的问题是从我的插件配置依赖管理插件似乎不起作用。我需要在 test-service/build.gradle 中重复dependencyManagement

这是由于第一个 if 块中的 return 语句造成的。您不仅跳过了应用依赖管理插件的逻辑,还跳过了导入 Spring Cloud bom 的逻辑。

如果没有 return 语句,您的示例项目将使用 ./gradlew clean build 为我成功构建。

【讨论】:

当然你是对的。删除此返回后,它就像一个魅力。非常感谢您的快速帮助。

以上是关于Spring引导多个gradle项目依赖管理->无法更改配置的依赖关系的主要内容,如果未能解决你的问题,请参考以下文章

使用spring依赖管理无法解析依赖

使用 spring boot gradle 插件无法使用依赖管理执行 junit5 测试

Gradle:使用 Spring Boot 依赖项构建“fat jar”

多模块 Spring Boot 项目中的 Gradle 依赖插件

从 Spring 依赖管理获取 Hibernate 版本以在 Gradle 中配置插件

如何使用带有 Spring 的 Gradle 依赖管理插件的分类器的 dependencyManagement 版本?