Cloud TT

导航

 

If you need to build a runnable spring-based JAR using maven, there could be some problems in the spring's configuration parsing. You know, to build a runnable JAR we have to include in the JAR all the dependencies, and Maven can help a lot in this, for example using the maven-assembly-plugin.

Here is a sample configuration of such plugin:

<plugin>
                        <groupId>org.apache.maven.plugins</groupId>
                        <artifactId>maven-assembly-plugin</artifactId>
                        <version>2.2-beta-5</version>
                        <configuration>
                                <descriptorRefs>
                                        <descriptorRef>jar-with-dependencies</descriptorRef>
                                </descriptorRefs>
                                <archive>
                                        <manifest>
                                                <mainClass>fully.qualified.name.of.MainClass</mainClass>
                                        </manifest>
                                </archive>
                        </configuration>
                </plugin> 

The plugin works well, but if you have more than the simple spring-core dependency, than you could have an Exception like: 
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/security]

The problem is that spring uses in each module's JAR two meta files:

  • META-INF/spring.handlers
  • META-INF/spring.schemas

such files are used in conjuction with configurations' XML Schemas to validate the application configuration even if the application is executed off-line. Because each Spring module brings these files, when the assemply plugin runs, it simply overwrites multiple times such files in the META-INF/ directory of the resulting JAR.
As result, we have that some configurations can't be validated and so the BeanDefinitionParsingException is thrown.

To avoid the problem we can use the maven-shade-plugin that performs some transformations to the resulting JAR's files. Here is an example configuration:

          <plugin>
                        <groupId>org.apache.maven.plugins</groupId>
                        <artifactId>maven-shade-plugin</artifactId>
                        <version>1.4</version>
                        <executions>
                                <execution>
                                        <phase>package</phase>
                                        <goals>
                                                <goal>shade</goal>
                                        </goals>
                                        <configuration>
                                                <transformers>
                                                        <transformer
                                                                        implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                                                                <mainClass>fully.qualified.name.of.MainClass</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>
                                </execution>
                        </executions>
                </plugin>

As you can see we are specifying something more than the MainClass: we are also saying that when spring.handlers and spring.schemas files are found, their contents must be appended to already existing files in the META-INF directory.

Running the maven package goal, we'll now get a working spring-based runnable JAR! 

  

posted on 2011-09-21 14:59  AnsonYang  阅读(657)  评论(0编辑  收藏  举报