Wednesday, November 9, 2011

Maven Tomcat Plugin: Selecting an XML Parser

The Tomcat Maven Plugin is a great tool for quickly working through the cycle of making and verifying changes in a webapp. One such app I was working with included an XML parser from Oracle:

  oracle:oracle_xmlparserv2:jar:10.2.0.3:compile

The inclusion of the parser created a problem as it did not take kindly to a document parsed during startup, causing an error:

  $ mvn tomcat:run 
...
Caused by: oracle.xml.parser.schema.XSDException: Duplicated definition for: 'identifiedType'
at oracle.xml.parser.schema.XSDBuilder.buildSchema(XSDBuilder.java:731)
at oracle.xml.parser.schema.XSDBuilder.build(XSDBuilder.java:435)
at oracle.xml.parser.schema.XSDValidator.processSchemaLocation(XSDValidator.java:879)
at oracle.xml.parser.schema.XSDValidator.startElement(XSDValidator.java:496)
at oracle.xml.parser.v2.NonValidatingParser.parseElement(NonValidatingParser.java:1224)
at oracle.xml.parser.v2.NonValidatingParser.parseRootElement(NonValidatingParser.java:311)
at oracle.xml.parser.v2.NonValidatingParser.parseDocument(NonValidatingParser.java:278)
... 52 more

A colleague of mine at work pointed at that you can select another parser through system properties, so I wanted to share his solution here:

  $ mvn tomcat:run \
-DXMLPARSER=XERCES \
-DXSLENGINE=XERCES \
-Djavax.xml.parsers.DocumentBuilderFactory=org.apache.xerces.jaxp.DocumentBuilderFactoryImpl \
-Djavax.xml.transform.TransformerFactory=org.apache.xalan.processor.TransformerFactoryImpl \
-Djavax.xml.parsers.SAXParserFactory=org.apache.xerces.jaxp.SAXParserFactoryImpl

The above selects a JAXP parser from Apache, requiring Xerces and Xalan:

  xerces:xercesImpl:${xercesImpl.version}
xalan:xalan:${xalan.version}

To avoid having to script the above command or have to remember it, you can add the settings to the plugin definition:

    <plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>tomcat-maven-plugin</artifactId>
<version>1.0</version>
<configuration>
<port>${tomcatPort}</port>
<path>/${project.artifactId}-${project.version}</path>
<systemProperties>
<env>${env}</env>
<tomcatPort>${tomcatPort}</tomcatPort>
<XMLPARSER>XERCES</XMLPARSER>
<XSLENGINE>XERCES</XSLENGINE>
<javax.xml.parsers.DocumentBuilderFactory>org.apache.xerces.jaxp.DocumentBuilderFactoryImpl</javax.xml.parsers.DocumentBuilderFactory>
<javax.xml.transform.TransformerFactory>org.apache.xalan.processor.TransformerFactoryImpl</javax.xml.transform.TransformerFactory>
<javax.xml.parsers.SAXParserFactory>org.apache.xerces.jaxp.SAXParserFactoryImpl</javax.xml.parsers.SAXParserFactory>
</systemProperties>
</configuration>
<dependencies>
<dependency>
<groupId>xerces</groupId>
<artifactId>xercesImpl</artifactId>
<version>${xercesImpl.version}</version>
</dependency>
<dependency>
<groupId>xalan</groupId>
<artifactId>xalan</artifactId>
<version>${xalan.version}</version>
</dependency>
</dependencies>
</plugin>

Hope this helps anyone else who may run into a similar situation.

No comments:

Post a Comment