shadow
shadow copied to clipboard
Dynamic Project Dependency Exclusion
My build process involves using a local project dependency for development but when it comes time to use shadow(Jar) we want to exclude that project dependency out for a runtime classpath manifest entry to a jar of that project. My approach was to go about it this way:
dependencies { projectsToSwap.collect {project(':' + it)}.each{exclude(it)} }
projectsToSwap is a collection that contains the intersection of a recursive set of dependency projects of the project being built and a list of known projects that we want to exclude for their runtime jar counterparts. The basic gist is a string of a project name that I need to exclude is being used to get the project object and then providing that as the input to the exclude function. From the documentation it 'looks' like what is described:
exclude(project(":myclient"))
However when it is done in this way it results in an unexpected error:
FAILURE: Build failed with an exception.
- What went wrong: No signature of method: com.github.jengelman.gradle.plugins.shadow.internal.DefaultDependencyFilter$_dependency_closure3.doCall() is applicable for argument types: (org.gradle.api.internal.file.DefaultFileVisitDetails) values: [file '/path-to-project-being-built-directory/build/classes/main/com'] Possible solutions: doCall(org.gradle.api.artifacts.ResolvedDependency), findAll(), findAll(), isCase(java.lang.Object), isCase(java.lang.Object)
I'm confused by it returning a DefaultFileVisitDetails type within that context, but also why it is showing the path of the project being built instead of at least the path to the project that I'm attempting to exclude.
Edit: For anyone else that encounters this using a for loop allows the removal of the inner closure and operates as expected. I'm still relatively new to Gradle and Groovy by extension but I'm guessing this may be related to the Each closure and possibly not something erroneous in Shadow.
for (projectNameToSwap in projectsToSwap) { exclude(project(':' + projectNameToSwap)) }
Project dependencies are not handled correctly at the moment. This is because of the way the files are resolved and such. It's an area that needs some improvement.
The cleanest solution to me would be to create a new configuration that duplicates your dependencies excluding the myclient
project and configure shadowJar
to use that.
ext.commonLibs = ["foo:foo:1.0", "bar:foo:2.1"]
configurations {
deploy
}
dependencies {
compile commonLibs
compile project(":myclient")
deploy commonLibs
}
shadowJar {
configurations ["deploy"]
}