Qeychon
Qeychon

Reputation: 491

Unable to locate Spring NamespaceHandler util

When I execute my java project with spring v.3.1 , so i get following error:

Bean 'configParser'; nested exception is 

org.springframework.beans.factory.parsing.BeanDefinitionParsingException: Configuration problem: Unable to locate Spring NamespaceHandler for XML schema namespace [http://www.springframework.org/schema/util]
Offending resource: class path resource [Services.xml]
Bean 'configParser'

My POM has following dependency:

<dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>3.1.2.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>3.1.2.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-tx</artifactId>
            <version>3.1.2.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>3.1.2.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
            <version>3.1.2.RELEASE</version>
        </dependency>

And my Service.xml file:

    <?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:util="http://www.springframework.org/schema/util"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
 http://www.springframework.org/schema/util  http://www.springframework.org/schema/util/spring-util-3.1.xsd">

    <bean id="configParser" class="com.cc.mp.srv.core.parser.ConfigParser">
        <property name="file" >
            <util:constant static-field="com.cc.mp.srv.main.Main.FILE_NAME"/>
        </property>
    </bean>

Why could not locate the utility schema? I insert the core dependency in the pom file. The version number are also the same. What needs Spring yet?

EDIT

Loading schema mappings from [META-INF/spring.schemas]
2015-01-31 18:56:11,553 DEBUG (main) [org.springframework.beans.factory.xml.PluggableSchemaResolver] - Loaded schema mappings: {http://www.springframework.org/schema/tx/spring-tx-2.5.xsd=org/springframework/transaction/config/spring-tx-2.5.xsd, http://www.springframework.org/schema/tx/spring-tx-3.1.xsd=org/springframework/transaction/config/spring-tx-3.1.xsd, http://www.springframework.org/schema/tx/spring-tx-2.0.xsd=org/springframework/transaction/config/spring-tx-2.0.xsd, http://www.springframework.org/schema/tx/spring-tx.xsd=org/springframework/transaction/config/spring-tx-3.1.xsd, http://www.springframework.org/schema/tx/spring-tx-3.0.xsd=org/springframework/transaction/config/spring-tx-3.0.xsd}

If the debug messages is output, then it can be recognized that various version number is used. Could be the reason? How can the numbers be defined?

I also use the maven-assembly-plugin to create a executable jar file.

Upvotes: 10

Views: 10036

Answers (3)

user2497161
user2497161

Reputation: 1

All the spring jars have spring.schemas and spring.handlers (which take care of the namespace handling) files in their respective META-INFs. Those files will get overwritten by each other. You will need to use the shade plugin (instead of assembly) with ResourceTransformers. The two combined, will merge the file content of the same file name onto one file. An example of the plugin for spring use would be something like this: (obtained from the ResourceTransformer link above). The two combined, will merge the file content of the same file name onto one file

<build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-shade-plugin</artifactId>
        <version>2.3</version>
        <executions>
          <execution>
            <phase>package</phase>
            <goals>
              <goal>shade</goal>
            </goals>
            <configuration>
              <transformers>
                <transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
                  <resource>META-INF/spring.handlers</resource>
                </transformer>
                <transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
                  <resource>META-INF/spring.schemas</resource>
                </transformer>
              </transformers>
            </configuration>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>

Upvotes: 0

helmy
helmy

Reputation: 9507

I ran into a similar issue with the maven-shade-plugin. The solution in my case was covered by this solution.

Basically you have to add an AppendingTransformer to your maven-shade-plugin configuration in pom.xml. Add the 2 AppendingTransformer entries from below:

<configuration>
    <outputDirectory>${basedir}/bin</outputDirectory>
    <finalName>myName</finalName>
    <transformers>
        <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
            <mainClass>com.foo.MyApp</mainClass>
        </transformer>
        <transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
            <resource>META-INF/spring.handlers</resource>
        </transformer>
        <transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
            <resource>META-INF/spring.schemas</resource>
        </transformer>
    </transformers>
...
</configuration>

Upvotes: 3

Ralph
Ralph

Reputation: 120811

The Schema http://www.springframework.org/schema/util/spring-util.xsd, http://www.springframework.org/schema/util/spring-util-3.1.xsd (and the one with the versions) come with spring-beans-<version>.RELEASE.jar

Add this jar to your dependencies:

<dependency>
     <groupId>org.springframework</groupId>
     <artifactId>spring-beans</artifactId>
     <version>3.1.2.RELEASE</version>
 </dependency>

The problem with maven-assembly-plugin:

You wrote:

I also use the maven-assembly-plugin to create a executable jar file.

Ah... I guess that the maven-assembly-plugin is the cause for that problem. This is because the schema resolution mechanism works this way: Spring provides the XSD files with there jars. Within the jar, in the folder META-INF is a file schema.info. This file contains a listing of all XSD fiels and there locations (in the jar) provided by this jar.

example: spring.schema of spring-beans-3.1.1.RELEASE.jar

http\://www.springframework.org/schema/beans/spring-beans-2.0.xsd=org/springframework/beans/factory/xml/spring-beans-2.0.xsd
http\://www.springframework.org/schema/beans/spring-beans-2.5.xsd=org/springframework/beans/factory/xml/spring-beans-2.5.xsd
http\://www.springframework.org/schema/beans/spring-beans-3.0.xsd=org/springframework/beans/factory/xml/spring-beans-3.0.xsd
http\://www.springframework.org/schema/beans/spring-beans-3.1.xsd=org/springframework/beans/factory/xml/spring-beans-3.1.xsd
http\://www.springframework.org/schema/beans/spring-beans.xsd=org/springframework/beans/factory/xml/spring-beans-3.1.xsd
http\://www.springframework.org/schema/tool/spring-tool-2.0.xsd=org/springframework/beans/factory/xml/spring-tool-2.0.xsd
http\://www.springframework.org/schema/tool/spring-tool-2.5.xsd=org/springframework/beans/factory/xml/spring-tool-2.5.xsd
http\://www.springframework.org/schema/tool/spring-tool-3.0.xsd=org/springframework/beans/factory/xml/spring-tool-3.0.xsd
http\://www.springframework.org/schema/tool/spring-tool-3.1.xsd=org/springframework/beans/factory/xml/spring-tool-3.1.xsd
http\://www.springframework.org/schema/tool/spring-tool.xsd=org/springframework/beans/factory/xml/spring-tool-3.1.xsd
http\://www.springframework.org/schema/util/spring-util-2.0.xsd=org/springframework/beans/factory/xml/spring-util-2.0.xsd
http\://www.springframework.org/schema/util/spring-util-2.5.xsd=org/springframework/beans/factory/xml/spring-util-2.5.xsd
http\://www.springframework.org/schema/util/spring-util-3.0.xsd=org/springframework/beans/factory/xml/spring-util-3.0.xsd
http\://www.springframework.org/schema/util/spring-util-3.1.xsd=org/springframework/beans/factory/xml/spring-util-3.1.xsd
http\://www.springframework.org/schema/util/spring-util.xsd=org/springframework/beans/factory/xml/spring-util-3.1.xsd

So and now you have different jars (spring-beans, spring-tx, spring-aop, spring-context...) , that all contains a META-INF/spring.schemas file, with different content. On the other hand you use maven-assembly-plugin to aggregate the content of all the jar files in a single one.

I guess you will have this problem with the spring.handlers file too.

It looks like you can configure the maven-assembly-plugin to merge this files. see: this answer of How can I merge resource files in a Maven assembly?

An alternative solution would using the spring-boot-maven-plugin instead of maven-assembly-plugin

 <plugin>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-maven-plugin</artifactId>
     <version>1.2.1</version>
     <executions>
        <execution>
            <goals>
                <goal>repackage</goal>
            </goals>
        </execution>
    </executions>
    <configuration>
        <mainClass>YOUR.MAIN.CLASS</mainClass>
    </configuration>
 </plugin>

(or use the maven-shade-pluging)

Upvotes: 13

Related Questions