Maven, Spring, and the Shade Uber-Jar

The Maven Shade plugin creates a Uber-jar which is a jar of a given maben project and all of it’s runtime dependencies. This is a handy tool, especially when you make the uber jar executable.

http://maven.apache.org/plugins/maven-shade-plugin/examples/executable-jar.html

I ran into a snag while creating this jar, however, the symptoms of which were that the project would run fine from Eclipse, but not when I ran it externally (ie. java -jar uber.jar). Specifically, I was getting the following exception:

Exception in thread “main” org.springframework.beans.factory.parsing.BeanDefinitionParsingException: Configuration problem: Unable to locate Spring NamespaceHandler for XML schema namespace p

Some googling lead me to this post:

http://blog.idm.fr/2009/09/maven-assembly-plugin-and-spring-namespace-handlers.html

Essentially, the uber-jar creation process ran into problems when populating the META-INF folder, specifically each of my included spring jars wanted to create a META-INF/spring.handlers to handle the custom namespaces used in the spring configuration xml files.

Each jar overwrote the spring.handlers file put there by the last one, and so when the jar creation was finished, only the last file was included, and so the only available namespace handlers were those for the last part of spring that was included.

The simple solution was to create my own spring.handlers file in META-INF which contained all the needed namespace handers for the entire project, like so:

http\://www.springframework.org/schema/p=org.springframework.beans.factory.xml.SimplePropertyNamespaceHandler
http\://www.springframework.org/schema/util=org.springframework.beans.factory.xml.UtilNamespaceHandler

http\://www.springframework.org/schema/aop=org.springframework.aop.config.AopNamespaceHandler

http\://www.springframework.org/schema/context=org.springframework.context.config.ContextNamespaceHandler
http\://www.springframework.org/schema/jee=org.springframework.ejb.config.JeeNamespaceHandler
http\://www.springframework.org/schema/lang=org.springframework.scripting.config.LangNamespaceHandler
http\://www.springframework.org/schema/integration=org.springframework.integration.config.xml.IntegrationNamespaceHandler

Once this was completed, I had a nice (big) jar that I could run.

It's only fair to share...
Share on FacebookGoogle+Tweet about this on TwitterShare on LinkedIn

Leave a Reply