Maven Assembly plugin and Spring Namespace handlers

| No Comments

Yesterday, I came accross a weird error when working with a Spring-enabled application. It was working fine within Eclipe but wouldn't run on the command line:

Exception in thread "main" org.springframework.beans.factory.parsing.BeanDefinitionParsingException: Configuration problem: Unable to locate Spring NamespaceHandler for XML schema namespace [http://www.springframework.org/schema/p]

I knew that Spring classes were in the classpath, but I didn't know why they were not found, or rather why the association between the namespace and the handler was not established.

By looking at Spring's documentation, I found a chapter that explained that you needed to implement the NamespaceHandler interface to map a namespace to a handler. I quickly found the handler that was not mapped: SimplePropertyNamespaceHandler.

The class is instanciated by reflection which means I couldn't use Eclipse to find callers. Instead, I simply put a breakpoint on the init() method and ran the application. That way, I found that DefaultNamespaceHandlerResolver was instanciating the handler, and that the getHandlerMappings() method was responsible for loading namespace-handler mappings.

The code is quite clear: it loads all the files named META-INF/spring.handlers. And here it is! There is more than one file named this way: there is one in spring-beans, one in spring-context, one in spring-aop, etc.

The issue is that, to make the application work outside Eclipse, we use the Maven Assembly plugin. It expands all the dependent JARs into the final JAR. This means it cannot put several files with the same name in the package and it has to choose one of the spring.handlers files.

As a workaround, I created my own spring.handlers with the content from all the spring.handlers files I could find in Spring packages. You could wonder how this works because this is only one more file to choose from, but it looks like that the local file is picked first and is not overriden by files from dependent packages!

Here is the file I created:

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

I found a few references to this issue:

Leave a comment

About this Entry

This page contains a single entry by Alexis Seigneurin published on September 17, 2009 9:40 AM.

Hudson Tray Tracker: version 0.9.3 was the previous entry in this blog.

Java HashSet considered wasteful is the next entry in this blog.

Find recent content on the main index or look in the archives to find all content.