Chapter 4. Integrating Axiom into your project

Table of Contents

Using Axiom in a Maven 2 project
Adding Axiom as a dependency
Managing the JAF dependency
Applying application wide configuration
Changing the default StAX factory settings
Migrating from older Axiom versions

Using Axiom in a Maven 2 project

Adding Axiom as a dependency

If your project uses Maven 2, it is fairly easy to add Axiom to your project. Simply add the following entries to the dependencies section of pom.xml:

<dependency>
    <groupId>org.apache.ws.commons.axiom</groupId>
    <artifactId>axiom-api</artifactId>
    <version>1.2.19</version>
</dependency>
<dependency>
    <groupId>org.apache.ws.commons.axiom</groupId>
    <artifactId>axiom-impl</artifactId>
    <version>1.2.19</version>
    <scope>runtime</scope>
</dependency>

All Axiom releases are deployed to the Maven central repository and there is no need to add an entry to the repositories section. However, if you want to work with the development (snapshot) version of Axiom, it is necessary to add the Apache Snapshot Repository:

<repository>
    <id>apache.snapshots</id>
    <name>Apache Snapshot Repository</name>
    <url>http://repository.apache.org/snapshots/</url>
    <releases>
        <enabled>false</enabled>
    </releases>
</repository>
[Tip]

If you are working on another Apache project, you don't need to add the snapshot repository in the POM file since it is already declared in the org.apache:apache parent POM.

Managing the JAF dependency

Axiom requires the Java Activation Framework (JAF) to work. There are two commonly used incarnations of this library: one is Sun's reference implementation, the other is part of the Geronimo project. Axiom declares a dependency on the Geronimo version. If your project uses another library that depends on JAF, but that refers to Sun's implementation, your project will end up with dependencies on two different artifacts implementing the same API.

If you prefer Sun's implementations, then you should change the declaration of the Axiom dependencies in your POM file as follow:

<dependency>
    <groupId>org.apache.ws.commons.axiom</groupId>
    <artifactId>axiom-xxx</artifactId>
    <version>1.2.19</version>
    <exclusions>
        <exclusion>
            <groupId>org.apache.geronimo.specs</groupId>
            <artifactId>geronimo-activation_1.1_spec</artifactId>
        </exclusion>
    </exclusions>
</dependency>

If you prefer Geronimo's implementation, then you need to identify the libraries depending on Sun's artifact (javax.activation:activation) and add the relevant exclusions. You can use mvn dependency:tree to easily identify where a transitive dependency comes from.

Applying application wide configuration

Sometimes it is necessary to customize some particular aspects of Axiom for an entire application. There are several things that can be configured through system properties and/or property files. This is also important when using third party applications or libraries that depend on Axiom.

Changing the default StAX factory settings

[Note]

The information in this section only applies to XMLStreamReader or XMLStreamWriter instances created using StAXUtils (see the section called “Creating stream readers and writers using StAXUtils). Readers and writers created using the standard StAX APIs will keep their default settings as defined by the implementation (or dictated by the StAX specifications).

[Note]

The feature described in this section was introduced in Axiom 1.2.9.

When creating a new XMLInputFactory (resp. XMLInputFactory), StAXUtils looks for a property file named XMLInputFactory.properties (resp. XMLOutputFactory.properties) in the classpath, using the same class loader as the one from which the factory is loaded (by default this is the context classloader). If a corresponding resource is found, the properties in that file are applied to the factory using the XMLInputFactory#setProperty (resp. XMLOutputFactory#setProperty) method.

This feature can be used to set factory properties of type Boolean, Integer and String. The following sections present some sample use cases.

Changing the serialization of the CR-LF character sequence

Section 2.11 of [XML] specifies that an XML processor must behave as if it normalized all line breaks in external parsed entities (including the document entity) on input, before parsing, by translating both the two-character sequence #xD #xA and any #xD that is not followed by #xA to a single #xA character. This implies that when a Windows style line ending, i.e. a CR-LF character sequence is serialized literally into an XML document, the CR character will be lost during deserialization. Depending on the use case this may or may not be desirable.

The only way to strictly preserve CR characters is to serialize them as character entities, i.e. &#xD;. This is the default behavior of Woodstox. This can be easily checked using the following Java snippet:

OMFactory factory = OMAbstractFactory.getOMFactory();
OMElement element = factory.createOMElement("root", null);
element.setText("Test\r\nwith CRLF");
element.serialize(System.out);

This code produces the following output:

<root>Test&#xd;
with CRLF</root>
[Note]

From Axiom's point of view this is actually a reasonable behavior. The reason is that when creating an OMText node programmatically, it is easy for the user code to normalize the text content to avoid the appearance of the character entity. On the other hand, if the default behavior was to serialize CR-LF literally (implying that the CR character will be lost during deserialization), it would be difficult (if not impossible) for user code that needs to strictly preserve the text data to construct the object model in such a way as to force serialization of the CR as character entity.

In some cases this behavior may be undesirable[1]. Fortunately Woodstox allows to modify this behavior by changing the value of the com.ctc.wstx.outputEscapeCr property on the XMLOutputFactory. If Axiom is used (and in particular StAXUtils) than this can be achieved by adding a XMLOutputFactory.properties file with the following content to the classpath (in the default package):

com.ctc.wstx.outputEscapeCr=false

Now the output of the Java snippet shown above will be:

<root>Test
with CRLF</root>

Preserving CDATA sections during parsing

By default, StAXUtils creates StAX parsers in coaelescing mode. In this mode, the parser will never return two character data events in sequence, while in non coaelescing mode, the parser is allowed to break up character data into smaller chunks and to return multiple consecutive character events, which may improve throughput for documents containing large text nodes. It should be noted that StAXUtils overrides the default settings mandated by the StAX specification, which specifies that by default, a StAX parser must be in non coalescing mode. The primary reason is compatibility: older versions of Woodstox had coalescing switched on by default.

A side effect of the default settings chosen by Axiom is that by default, CDATA sections are not reported by parser created by StAXUtils. The reason is that in coalescing mode, the parser will not only coaelsce adjacent text nodes, but also CDATA sections. Applications that require correct reporting of CDATA sections should therefore disable coalescing. This can be achieved by creating a XMLInputFactory.properties file with the following content:

javax.xml.stream.isCoalescing=false

Migrating from older Axiom versions

The release notes provide information about changes in Axiom that might impact existing code when migrating from an older version of Axiom. Note that they are not meant as a change log that lists all changes or new features. Also, before upgrading to a newer Axiom version, you should always check if your code uses methods or classes that have been deprecated. You should fix all deprecation warnings before changing the Axiom version. In general the Javadoc of the deprecated class or method gives you a hint on how to change your code.



[1] See WSTX-94 for a discussion about this.