How do I use the Gradle Shadow Plugin to merge spring.handlers and spring.schemas files of multiple Spring jar dependencies?

I am building a project that relies on several Spring libraries. I applied the shadow plugin (https://github.com/johnrengelman/shadow) and ran the runShadow task and get the following error:

Configuration problem: Unable to locate Spring NamespaceHandler for XML schema namespace [http://www.springframework.org/schema/context]

After doing some research, I think the problem is that each of the Spring library contains a spring.handlers and spring.schemas files under a META-INF directory, so they are overriding each other. There is the maven shade plugin which takes care of this problem for maven, so I assume that Shadow which is roughly the equivalent of Maven’s Shade plugin can also merge all the separate spring.handlers and spring.schemas files into just one that includes all of the configurations. I just don’t know what is the syntax to use – there is only a snippet about a Transformers api in the github README for Shadow. Has anyone run into this issue with Gradle before? If so, how did you solve it?

Thank you very much.

Should be able to do something like this.

shadowJar {

mergeServiceFiles(‘META-INF’) {

include ‘spring.*’

}

}

Thank you for the reply.

I first tried adding that snippet of code to the build file as shown below and ran the shadowJar task but I got the following error:

Could not find method mergeServiceFiles() for arguments [META-INF, build_uikua424h66rqmcd6pekgkm62$_run_closure1_closure3@28341220] on project ':EmailConsumer'

I then tried variations of the syntax. The first was:

shadowJar {
    mergeServiceFiles('META-INF')
    include 'spring.*'
}

after which I ran shadowJar followed by runShadow:

Error: Could not find or load main class com.se.email.submexch.consum.PollingConsumer

which is rather odd. Perhaps the Manifest file got merged as well?

I also tried

shadowJar{
      mergeServiceFiles('META-INF/spring.*')
}

and ran shadowJar followed by runShadow, but that just gives me the same ‘could not find namespace handler’ that I mentioned in my original post. Any ideas?

Try

shadowJar {

mergeServiceFiles {

path ‘META-INF’

include ‘spring.*’

}

}

That also gave me the ‘unable to find namespace handler’ error. Thank you very much for your help – but I think I will go the route of manually merging the files for now.

I tested it with the following configuration and was able to get it to work. By “work”, I mean the resultant files were correctly concatenated.

import com.github.jengelman.gradle.plugins.shadow.transformers.ServiceFileTransformer

shadowJar {

transform(ServiceFileTransformer) {

path = ‘META-INF’

include ‘spring.*’

}

}

2 Likes