How to copy a single set of ALL the subprojects dependencies

I have a project with several subprojects and I want to copy all of the runtime dependencies to the execution environment. The following task does this, but as my subprojects have essentially identical dependencies, the same jar files are copied over and over again (once per subproject)…I have looked and looked but cannot figure out how to get all the dependencies of the subprojects into a single set in order to only copy the depenedency once. If you have any idea how to do this, I’d really appreciate it. thanks!

p.s. I have tried setting the duplicatesStrategy = ‘exclude’ and it did not have the expected effect.

task installGatewayDeps(type: Copy) {
    onlyIf { System.env.KARAF_HOME }
    into "$System.env.KARAF_HOME/gateway/plugins"
    from gatewayPlugins.configurations.runtime
}
installGatewayDeps.eachFile { println "installing $it.path" }

I think the only way to accomplish this is to perform the copy in a single task in the root project.

task installSubprojectDeps(type: Copy) {
    onlyIf { System.env.KARAF_HOME }
    into "$System.env.KARAF_HOME/gateway/plugins"
    from subprojects.collect { it.configurations.runtime }
}

Thanks for the quick reply Mark,
In all the other answers I hand;e yet encountered the subprojects.collect {} construct.I tried this and unfortunately it produces the same results…”installing xxx.jar” once for each subproject.

This is a task that lives in the root build.gradle. I haven’t dug into the gradle code at all but I’m wondering if the eachFile is called as each file is processed or only for thse that are actually copied? Maybe I’m just seeing the evaluations fly by but the files are only copied once.

At any rate, not that big a deal to be spending anymore time on for me right now.

Thanks again.

I have followed this advice and produced this root project build.gradle script:

subprojects {
	repositories {
		jcenter()
	}
}

task stage(type: Copy) {
	into '../stage'
	from '../README.md'
	from '../RELEASE.md'
	into('bin') {
		subprojects { from tasks.withType(CreateStartScripts) }
	}
	into('doc') {
		from '../doc'
	}	
	into('lib') {
		from subprojects.collect { it.configurations.runtime } 
    }
}

Running gradle 3.5 in the root project results:

FAILURE: Build failed with an exception.

* Where:
Build file 'C:\Users\Pedro\Projetos\sts\gradle\build.gradle' line: 18

* What went wrong:
A problem occurred evaluating root project 'gradle'.
> Could not get unknown property 'runtime' for configuration container of type org.gradle.api.internal.artifacts.configurations.DefaultConfigurationContainer.

Am I missing something?

This is an evaluation order problem. A plugin such as the JavaPlugin is adding the runtime configuration, but it hasn’t been added yet when your from subprojects.collect { it.configuration.runtime } line executes.

You can apply the plugin earlier to all subprojects in the subprojects { ... } block, wrap the subprojects.collect { it.configurations.runtime } in { } to make it a closure that is evaluated later, or invert the evaluation order with evaluationDependsOnChildren().

1 Like