Saturday, March 27, 2010

Maven Shade & Spring Core Handlers

One more challenge I faced with,
Task description:
To create small Java CLI utility for some file-system and database operation

Java Technologies used:

Issue description:
To package the utility Maven Shade plug-in was used
It allow to create a single executable jar with all Maven dependencies included in

With a try to launch executable jar it failed to create Spring context

Spring context looked like:
<?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:context="http://www.springframework.org/schema/context"
xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.0.xsd">
...

</beans>


Error looked like:
Exception in thread "main" org.springframework.beans.factory.xml.XmlBeanDefinitionStoreException: Line 16 in XML document from class path resource [...] is invalid; nested exception is org.xml.sax.SAXParseException: cvc-elt.1: Cannot find the declaration of element 'beans'.

To describe with a few words Spring SAX parser failed to find beans name-space schema definition

Issue work around:
All Spring name-space XSD files are located within Spring jars
For example, spring-beans-2.0.xsd could be found in the
org/springframework/beans/factory/xml/spring-beans-2.0.xsd


Full global schema to local one mapping located in the META-INF\spring.schemas file
As to the spring-beans-2.0.xsd, record in the META-INF\spring.schemas file looks like:
http\://www.springframework.org/schema/beans/spring-beans-2.5.xsd=org/springframework/beans/factory/xml/spring-beans-2.5.xsd

spring.schemas file can occure not once in the all Maven dependencies and Maven Shade plugin override the result spring.schemas in the executable jar

To overcome this problem additional Shade plugin configuration needs

In my case they looks like:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>1.3.1</version>

<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>com.sabre.newgermanrail.dbitool.DbiTool</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>



This configuration declare to append files and not to overwrite

References
http://maven.apache.org/plugins/maven-shade-plugin/examples/resource-transformers.html


1 comments:

Anonymous said...

This is what I was looking for. Thanks. It halped me a lot